Skip to content

Commit 741f454

Browse files
committed
feat: initial sign action
0 parents  commit 741f454

26 files changed

Lines changed: 117600 additions & 0 deletions

.github/workflows/ci.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
build-and-test:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- uses: actions/setup-node@v4
16+
with:
17+
node-version: 20
18+
cache: npm
19+
20+
- name: Install dependencies
21+
run: npm ci
22+
23+
- name: Test
24+
run: npm test
25+
26+
- name: Build
27+
run: npm run build
28+
29+
- name: Check dist is committed
30+
run: |
31+
git diff --exit-code -- dist/ ':!dist/**/*.d.ts.map' || {
32+
echo "::error::dist/ is out of date. Run 'just build' (or 'npm run build') and commit the result."
33+
exit 1
34+
}
35+
36+
verify-commits:
37+
runs-on: ubuntu-latest
38+
steps:
39+
- uses: actions/checkout@v4
40+
with:
41+
fetch-depth: 0
42+
43+
- name: Verify commit signatures
44+
uses: auths-dev/auths-verify-github-action@v1
45+
with:
46+
fail-on-unsigned: true

.github/workflows/release.yml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Triggered by: python scripts/release.py --push
2+
3+
name: Release
4+
5+
on:
6+
push:
7+
tags:
8+
- 'v*.*.*'
9+
10+
permissions:
11+
contents: write
12+
13+
jobs:
14+
release:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v4
18+
with:
19+
fetch-depth: 0
20+
21+
- uses: actions/setup-node@v4
22+
with:
23+
node-version: 20
24+
cache: npm
25+
26+
- run: npm ci
27+
- run: npm test
28+
- run: npm run build
29+
30+
- name: Check dist is up to date
31+
run: git diff --exit-code -- dist/ ':!dist/**/*.d.ts.map'
32+
33+
# Dogfood: sign dist/index.js using ourselves
34+
- name: Sign and verify dist/index.js
35+
uses: ./
36+
with:
37+
passphrase: ${{ secrets.AUTHS_CI_PASSPHRASE }}
38+
keychain: ${{ secrets.AUTHS_CI_KEYCHAIN }}
39+
identity-repo: ${{ secrets.AUTHS_CI_IDENTITY_BUNDLE }}
40+
verify-bundle: ${{ secrets.AUTHS_CI_IDENTITY_BUNDLE_JSON }}
41+
files: 'dist/index.js'
42+
verify: true
43+
note: 'GitHub Actions release — ${{ github.ref_name }}'
44+
45+
- name: Generate SHA256 checksums
46+
run: |
47+
cd dist
48+
sha256sum index.js > index.js.sha256
49+
if [ -f index.js.auths.json ]; then
50+
sha256sum index.js.auths.json >> index.js.sha256
51+
fi
52+
cat index.js.sha256
53+
54+
- name: Create GitHub Release
55+
uses: softprops/action-gh-release@v2
56+
with:
57+
generate_release_notes: true
58+
make_latest: true
59+
files: |
60+
dist/index.js.auths.json
61+
dist/index.js.sha256
62+
body: |
63+
## Auths Sign GitHub Action
64+
65+
Sign build artifacts in CI using [Auths](https://github.com/auths-dev/auths) identity keys.
66+
67+
### Usage
68+
69+
```yaml
70+
- uses: auths-dev/sign@${{ github.ref_name }}
71+
with:
72+
token: ${{ secrets.AUTHS_CI_TOKEN }}
73+
files: 'dist/index.js'
74+
verify: true
75+
```
76+
77+
See the [README](https://github.com/auths-dev/sign#readme) for full configuration options.
78+
79+
- name: Update floating major tag
80+
run: |
81+
TAG="${GITHUB_REF_NAME}"
82+
MAJOR="${TAG%%.*}"
83+
git tag -f "$MAJOR" "$TAG"
84+
git push origin "$MAJOR" --force

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Dependencies
2+
node_modules/
3+
4+
# TypeScript build info
5+
*.tsbuildinfo
6+
7+
# TypeScript declaration sourcemaps (contain local build paths)
8+
dist/**/*.d.ts.map
9+
10+
# Local tool directories
11+
.flow/

action.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: 'Sign Artifacts with Auths'
2+
description: 'Sign build artifacts using Auths identity keys in CI'
3+
author: 'auths'
4+
5+
inputs:
6+
token:
7+
description: 'AUTHS_CI_TOKEN JSON (preferred) — contains passphrase, keychain, identity repo, and verify bundle'
8+
required: false
9+
default: ''
10+
passphrase:
11+
description: 'Auths device key passphrase (fallback when token is not provided)'
12+
required: false
13+
default: ''
14+
keychain:
15+
description: 'Base64-encoded encrypted keychain file (fallback when token is not provided)'
16+
required: false
17+
default: ''
18+
identity-repo:
19+
description: 'Base64-encoded tar.gz of ~/.auths identity repo (fallback when token is not provided)'
20+
required: false
21+
default: ''
22+
verify-bundle:
23+
description: 'Identity bundle JSON for post-sign verification (fallback when token is not provided)'
24+
required: false
25+
default: ''
26+
files:
27+
description: 'Glob patterns for files to sign, one per line'
28+
required: true
29+
verify:
30+
description: 'Verify each file after signing using the verify bundle from the token'
31+
required: false
32+
default: 'false'
33+
device-key:
34+
description: 'Alias of the device key to sign with'
35+
required: false
36+
default: 'ci-release-device'
37+
note:
38+
description: 'Optional note to include in the attestation'
39+
required: false
40+
default: ''
41+
auths-version:
42+
description: 'Auths CLI version to use (leave empty for latest)'
43+
required: false
44+
default: ''
45+
46+
outputs:
47+
signed-files:
48+
description: 'JSON array of file paths that were signed'
49+
attestation-files:
50+
description: 'JSON array of attestation file paths (.auths.json)'
51+
verified:
52+
description: 'Whether all signed files passed verification (empty string if verify was not requested)'
53+
54+
runs:
55+
using: 'node20'
56+
main: 'dist/index.js'
57+
58+
branding:
59+
icon: 'edit-3'
60+
color: 'blue'

dist/__tests__/installer.test.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export {};

dist/__tests__/main.test.d.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Integration tests for the sign action's run() flow.
3+
* Since run() executes at import time, we use jest.isolateModulesAsync.
4+
*/
5+
declare let mockInputs: Record<string, string>;
6+
declare let mockMultilineInputs: Record<string, string[]>;
7+
declare let mockOutputs: Record<string, string>;
8+
declare let mockFailed: string[];
9+
declare let mockWarnings: string[];
10+
declare let mockGlobFiles: string[];
11+
declare let mockExecExitCode: number;
12+
declare let mockExecOutputResult: {
13+
exitCode: number;
14+
stdout: string;
15+
stderr: string;
16+
};
17+
declare const mockResolveCredentials: jest.Mock<any, any, any>;
18+
declare const mockCleanupPaths: jest.Mock<any, any, any>;
19+
declare function resetMockState(): void;
20+
declare function runMain(): Promise<void>;

dist/__tests__/token.test.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export {};

0 commit comments

Comments
 (0)