Skip to content

Commit 090148b

Browse files
Sync from Lovable project — 2026-03-04 14:31 UTC
1 parent b68794e commit 090148b

File tree

5 files changed

+220
-0
lines changed

5 files changed

+220
-0
lines changed

LICENSE

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
This is free and unencumbered software released into the public domain.
2+
3+
Anyone is free to copy, modify, publish, use, compile, sell, or
4+
distribute this software, either in source code form or as a compiled
5+
binary, for any purpose, commercial or non-commercial, and by any
6+
means.
7+
8+
In jurisdictions that recognize copyright laws, the author or authors
9+
of this software dedicate any and all copyright interest in the
10+
software to the public domain. We make this dedication for the benefit
11+
of the public at large and to the detriment of our heirs and
12+
successors. We intend this dedication to be an overt act of
13+
relinquishment in perpetuity of all present and future rights to this
14+
software under copyright law.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19+
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22+
OTHER DEALINGS IN THE SOFTWARE.
23+
24+
For more information, please refer to <https://unlicense.org/>

README.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# AnchoringTrust/anchor-action
2+
3+
Anchor build artifacts to Bitcoin. One line in your workflow, zero manual proof handling.
4+
5+
## Usage
6+
7+
```yaml
8+
- uses: AnchoringTrust/anchor-action@v1
9+
with:
10+
file: build/output.tar.gz
11+
env:
12+
UMARISE_API_KEY: ${{ secrets.UMARISE_API_KEY }}
13+
```
14+
15+
That's it. Every build gets a `.proof` file — uploaded as a GitHub Actions artifact.
16+
17+
## What happens
18+
19+
1. Installs `@umarise/cli`
20+
2. Runs `umarise anchor <file>`
21+
3. Uploads `<file>.proof` as artifact
22+
23+
The proof bundle contains `certificate.json` + `proof.ots`. Verifiable offline, independent of Umarise.
24+
25+
## Inputs
26+
27+
| Input | Required | Default | Description |
28+
|---|---|---|---|
29+
| `file` | ✅ | — | Path to the file to anchor |
30+
| `upload-artifact` | — | `true` | Upload `.proof` as GitHub Actions artifact |
31+
32+
## Outputs
33+
34+
| Output | Description |
35+
|---|---|
36+
| `origin-id` | The `origin_id` from Umarise |
37+
| `hash` | SHA-256 hash of the file |
38+
| `proof-path` | Local path to the `.proof` file |
39+
40+
## Secrets
41+
42+
Add `UMARISE_API_KEY` to your repository secrets:
43+
Settings → Secrets and variables → Actions → New repository secret.
44+
45+
Get your key at [umarise.com/developers](https://umarise.com/developers).
46+
47+
## Full example
48+
49+
```yaml
50+
name: Build & Anchor
51+
52+
on:
53+
push:
54+
branches: [main]
55+
56+
jobs:
57+
build:
58+
runs-on: ubuntu-latest
59+
steps:
60+
- uses: actions/checkout@v4
61+
62+
- name: Build
63+
run: tar czf build.tar.gz dist/
64+
65+
- name: Anchor to Bitcoin
66+
uses: AnchoringTrust/anchor-action@v1
67+
with:
68+
file: build.tar.gz
69+
env:
70+
UMARISE_API_KEY: ${{ secrets.UMARISE_API_KEY }}
71+
```
72+
73+
## Verify offline
74+
75+
```bash
76+
# Download the .proof artifact from GitHub Actions
77+
unzip build.tar.gz.proof
78+
sha256sum build.tar.gz # compare with certificate.json
79+
ots verify proof.ots # verify against Bitcoin
80+
```
81+
82+
No Umarise server needed for verification.
83+
84+
## License
85+
86+
Unlicense (Public Domain)
87+

action.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: 'Umarise Anchor'
2+
description: 'Anchor files to Bitcoin via Umarise. Creates a .proof bundle for every build artifact.'
3+
author: 'Umarise'
4+
5+
branding:
6+
icon: 'shield'
7+
color: 'gray-dark'
8+
9+
inputs:
10+
file:
11+
description: 'Path to the file to anchor (e.g. build/output.tar.gz)'
12+
required: true
13+
upload-artifact:
14+
description: 'Upload the .proof file as a GitHub Actions artifact (default: true)'
15+
required: false
16+
default: 'true'
17+
18+
outputs:
19+
origin-id:
20+
description: 'The origin_id returned by Umarise'
21+
hash:
22+
description: 'The SHA-256 hash of the anchored file'
23+
proof-path:
24+
description: 'Path to the generated .proof file'
25+
26+
runs:
27+
using: 'node20'
28+
main: 'dist/index.js'

package.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "umarise-anchor-action",
3+
"version": "1.0.0",
4+
"private": true,
5+
"description": "GitHub Action — anchor files to Bitcoin via Umarise",
6+
"main": "dist/index.js",
7+
"scripts": {
8+
"build": "ncc build src/index.js -o dist"
9+
},
10+
"dependencies": {
11+
"@actions/core": "^1.11.1",
12+
"@actions/exec": "^1.1.1",
13+
"@actions/artifact": "^2.2.2"
14+
},
15+
"devDependencies": {
16+
"@vercel/ncc": "^0.38.1"
17+
},
18+
"license": "Unlicense"
19+
}

src/index.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* AnchoringTrust/anchor-action
3+
*
4+
* Thin wrapper around @umarise/cli.
5+
* Installs the CLI, runs `umarise anchor <file>`, uploads the .proof artifact.
6+
*/
7+
8+
const core = require('@actions/core');
9+
const exec = require('@actions/exec');
10+
const { DefaultArtifactClient } = require('@actions/artifact');
11+
const path = require('path');
12+
const fs = require('fs');
13+
14+
async function run() {
15+
try {
16+
const file = core.getInput('file', { required: true });
17+
const uploadArtifact = core.getInput('upload-artifact') !== 'false';
18+
19+
// Verify file exists
20+
const absPath = path.resolve(file);
21+
if (!fs.existsSync(absPath)) {
22+
throw new Error(`File not found: ${file}`);
23+
}
24+
25+
// Install @umarise/cli globally
26+
core.info('Installing @umarise/cli...');
27+
await exec.exec('npm', ['install', '-g', '@umarise/cli']);
28+
29+
// Run anchor command
30+
core.info(`Anchoring ${file}...`);
31+
let stdout = '';
32+
await exec.exec('umarise', ['anchor', file], {
33+
listeners: {
34+
stdout: (data) => { stdout += data.toString(); },
35+
},
36+
});
37+
38+
// Parse output for origin_id and hash
39+
const originMatch = stdout.match(/origin_id\s+([a-f0-9-]+)/i);
40+
const hashMatch = stdout.match(/hash computed:\s+(sha256:[a-f0-9]+)/i);
41+
const proofPath = `${absPath}.proof`;
42+
43+
if (originMatch) core.setOutput('origin-id', originMatch[1]);
44+
if (hashMatch) core.setOutput('hash', hashMatch[1]);
45+
core.setOutput('proof-path', proofPath);
46+
47+
// Upload .proof as artifact
48+
if (uploadArtifact && fs.existsSync(proofPath)) {
49+
core.info('Uploading .proof artifact...');
50+
const artifactName = `${path.basename(file)}.proof`;
51+
const client = new DefaultArtifactClient();
52+
await client.uploadArtifact(artifactName, [proofPath], path.dirname(proofPath));
53+
core.info(`✓ artifact uploaded: ${artifactName}`);
54+
}
55+
56+
core.info('✓ anchor-action complete');
57+
} catch (error) {
58+
core.setFailed(error.message);
59+
}
60+
}
61+
62+
run();

0 commit comments

Comments
 (0)