Skip to content

Commit c788f09

Browse files
authored
Merge pull request #7 from auths-dev/fn-1
feat: add artifact verification inputs/outputs
2 parents 0e6382a + 2cb7dc0 commit c788f09

17 files changed

Lines changed: 37703 additions & 4259 deletions

.auths/allowed_signers

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
# auths:managed — do not edit manually
2-
# Current identity (E6IXlw5-lnX88r3WZCt3u1qyN_Xlq7nQjtoTmuOfMIjI)
3-
z6MktnihicwetvA16FtHFynaJTn9eDZw51eizUEA1yGJCR4o@auths.local namespaces="git" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINT/yz5N7+GkzsRTHiyaueZbDy+fovwYUXyJ9uwD67tk
4-
# Previous identities
5-
z6MkipUqayiDZWM8j4YktjiEFZcCGw51YDVvLM7SrYPqLLyZ@auths.local namespaces="git" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEDeaOmUEcUjzChUedAsPyDO4mnjIa8j92fD9rGpuZd0
6-
z6MkhfnUUc2UJJ5C9sQQ7GvXmSbQJsdtNKV6HNYcQtTjc7xE@auths.local namespaces="git" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC/Ib83sxXogDnEVzLjFBkyC+DhP+cssbPzZAmQhB+Lz
7-
z6Mkio7WpoPy5EfeMJwhiZzePFch7xxuDeF9tpAf9q15nnHf@auths.local namespaces="git" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIECEt+3NgK9ws6M65lPSqW1FgWFjCYQVj1fsDedIvkRi
2+
# auths:attestation
3+
z6MkhPJCPXd5A9VN4wScJkxTtz6de7egZQx78vsiAT1vg3PZ@auths.local namespaces="git" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICuPK6OfYp7ngZp40Q+Dsrahhks472v6gPIMD0upCRnM
4+
# auths:manual

.github/workflows/ci.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,19 @@ jobs:
4444
uses: ./
4545
with:
4646
fail-on-unsigned: true
47+
48+
# TODO: Enable after first signed release (just release X.Y.Z runs auths artifact sign dist/index.js)
49+
# verify-artifacts:
50+
# runs-on: ubuntu-latest
51+
# needs: build-and-test
52+
# steps:
53+
# - uses: actions/checkout@v4
54+
# with:
55+
# fetch-depth: 0
56+
#
57+
# - name: Verify dist/index.js attestation
58+
# uses: ./
59+
# with:
60+
# identity-bundle: ... # provide bundle path or inline JSON
61+
# artifact-paths: 'dist/index.js'
62+
# fail-on-unattested: true

.github/workflows/release.yml

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Triggered by: python scripts/release.py --push
2+
# (tags vX.Y.Z and pushes, which triggers this workflow)
3+
14
name: Release
25

36
on:
@@ -13,6 +16,8 @@ jobs:
1316
runs-on: ubuntu-latest
1417
steps:
1518
- uses: actions/checkout@v4
19+
with:
20+
fetch-depth: 0
1621

1722
- uses: actions/setup-node@v4
1823
with:
@@ -26,33 +31,78 @@ jobs:
2631
- name: Check dist is up to date
2732
run: git diff --exit-code -- dist/ ':!dist/**/*.d.ts.map'
2833

34+
# --- Artifact signing (mirrors auths/auths release workflow) ---
35+
- name: Install auths CLI
36+
run: |
37+
curl -sL https://github.com/auths-dev/auths/releases/latest/download/auths-linux-x86_64.tar.gz | tar xz -C /usr/local/bin
38+
39+
- name: Sign dist/index.js
40+
env:
41+
AUTHS_PASSPHRASE: ${{ secrets.AUTHS_CI_PASSPHRASE }}
42+
AUTHS_CI_KEYCHAIN_B64: ${{ secrets.AUTHS_CI_KEYCHAIN }}
43+
AUTHS_CI_IDENTITY_BUNDLE_B64: ${{ secrets.AUTHS_CI_IDENTITY_BUNDLE }}
44+
AUTHS_KEYCHAIN_BACKEND: file
45+
AUTHS_KEYCHAIN_FILE: /tmp/auths-ci-keychain
46+
run: |
47+
if [ -z "$AUTHS_PASSPHRASE" ] || [ -z "$AUTHS_CI_KEYCHAIN_B64" ] || [ -z "$AUTHS_CI_IDENTITY_BUNDLE_B64" ]; then
48+
echo "::warning::Skipping artifact signing: AUTHS_CI_PASSPHRASE, AUTHS_CI_KEYCHAIN, and AUTHS_CI_IDENTITY_BUNDLE must all be set"
49+
exit 0
50+
fi
51+
52+
printf '%s' "$AUTHS_CI_KEYCHAIN_B64" | tr -d '[:space:]' | base64 -d > /tmp/auths-ci-keychain
53+
mkdir -p /tmp/auths-identity
54+
printf '%s' "$AUTHS_CI_IDENTITY_BUNDLE_B64" | tr -d '[:space:]' | base64 -d | tar -xz -C /tmp/auths-identity
55+
56+
if ! git -C /tmp/auths-identity rev-parse --git-dir > /dev/null 2>&1; then
57+
echo "::warning::Skipping artifact signing: AUTHS_CI_IDENTITY_BUNDLE does not contain a valid git repository"
58+
exit 0
59+
fi
60+
61+
auths artifact sign dist/index.js \
62+
--device-key ci-release-device \
63+
--note "GitHub Actions release — ${GITHUB_REF_NAME}" \
64+
--repo /tmp/auths-identity
65+
66+
echo "Signed dist/index.js → dist/index.js.auths.json"
67+
68+
- name: Generate SHA256 checksums
69+
run: |
70+
cd dist
71+
sha256sum index.js > index.js.sha256
72+
if [ -f index.js.auths.json ]; then
73+
sha256sum index.js.auths.json >> index.js.sha256
74+
fi
75+
cat index.js.sha256
76+
2977
- name: Create GitHub Release
3078
uses: softprops/action-gh-release@v2
3179
with:
3280
generate_release_notes: true
3381
make_latest: true
82+
files: |
83+
dist/index.js.auths.json
84+
dist/index.js.sha256
3485
body: |
3586
## Auths Verify GitHub Action
3687
37-
Verify commit signatures in your CI pipeline using [Auths](https://github.com/auths-dev/auths) identity keys.
38-
39-
### Features
40-
- Verifies SSH commit signatures against an allowed signers file or identity bundle
41-
- Auto-downloads the `auths` CLI at runtime
42-
- SHA256 checksum verification on downloaded binaries
43-
- Supports `pull_request` and `push` events with automatic commit range detection
44-
- GitHub Step Summary with per-commit verification results
45-
- Optional PR comments with fix instructions for unsigned commits
46-
- Skips merge commits and GPG-signed commits by default
88+
Verify commit signatures and artifact attestations in your CI pipeline using [Auths](https://github.com/auths-dev/auths) identity keys.
4789
4890
### Usage
4991
5092
```yaml
51-
- uses: auths-dev/auths-verify-github-action@v1
93+
- uses: auths-dev/auths-verify-github-action@${{ github.ref_name }}
5294
with:
5395
allowed-signers: '.auths/allowed_signers'
5496
```
5597
98+
**New: Artifact verification**
99+
```yaml
100+
- uses: auths-dev/auths-verify-github-action@${{ github.ref_name }}
101+
with:
102+
identity-bundle: ${{ secrets.AUTHS_IDENTITY_BUNDLE }}
103+
artifact-paths: 'dist/*.tar.gz'
104+
```
105+
56106
See the [README](https://github.com/auths-dev/auths-verify-github-action#readme) for full configuration options.
57107
58108
- name: Update floating major tag

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ dist/**/*.d.ts.map
1212

1313
# Local tool directories
1414
.deepeval/
15+
.flow/

action.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,18 @@ inputs:
3939
description: 'GitHub token used to post the PR comment (required when post-pr-comment is true)'
4040
required: false
4141
default: ''
42+
artifact-paths:
43+
description: 'Glob patterns for artifact files to verify, one per line (e.g., "dist/*.tar.gz")'
44+
required: false
45+
default: ''
46+
artifact-attestation-dir:
47+
description: 'Directory containing .auths.json attestation files (default: alongside artifacts)'
48+
required: false
49+
default: ''
50+
fail-on-unattested:
51+
description: 'Fail the action if any artifact lacks a valid attestation'
52+
required: false
53+
default: 'true'
4254

4355
outputs:
4456
verified:
@@ -51,6 +63,10 @@ outputs:
5163
description: 'Number of commits that passed verification'
5264
failed:
5365
description: 'Number of commits that failed verification'
66+
artifacts-verified:
67+
description: 'Whether all artifacts were verified (true/false)'
68+
artifact-results:
69+
description: 'JSON array of per-artifact verification results'
5470

5571
runs:
5672
using: 'node20'
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Integration tests for artifact verification in main.ts run() flow.
3+
*
4+
* Since run() is called at module load time, we use jest.isolateModules
5+
* to re-import the module with different mock configurations per test.
6+
*/
7+
declare let mockInputs: Record<string, string>;
8+
declare let mockMultilineInputs: Record<string, string[]>;
9+
declare let mockOutputs: Record<string, string>;
10+
declare let mockFailed: string[];
11+
declare let mockWarnings: string[];
12+
declare let mockGlobFiles: string[];
13+
declare let mockArtifactResults: any[];
14+
declare let mockVerifyCommitsResult: any[];
15+
declare const mockVerifyCommits: jest.Mock<any, any, any>;
16+
declare const mockEnsureAuthsInstalled: jest.Mock<any, any, any>;
17+
declare const mockVerifyArtifact: jest.Mock<any, any, any>;
18+
declare const mockRunPreflightChecks: jest.Mock<any, any, any>;
19+
declare function resetMockState(): void;
20+
declare function runMain(): Promise<void>;

0 commit comments

Comments
 (0)