Skip to content

Commit 4abdca8

Browse files
committed
ci: add GitHub Actions workflows
- Add CI workflow for testing and building - Configure semantic-release workflow for automated releases - Set up release workflow for npm publishing - Include test coverage reporting
1 parent def3342 commit 4abdca8

File tree

3 files changed

+295
-0
lines changed

3 files changed

+295
-0
lines changed

.github/workflows/ci.yml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
test:
16+
runs-on: ubuntu-latest
17+
strategy:
18+
matrix:
19+
node-version:
20+
- 18
21+
- 20
22+
- 22
23+
24+
steps:
25+
- name: Checkout code
26+
uses: actions/checkout@v4
27+
28+
- name: Setup Node.js ${{ matrix.node-version }}
29+
uses: actions/setup-node@v4
30+
with:
31+
node-version: ${{ matrix.node-version }}
32+
33+
- name: Enable Corepack
34+
run: corepack enable
35+
36+
- name: Install dependencies
37+
run: yarn install --frozen-lockfile
38+
39+
- name: Lint commit messages
40+
if: github.event_name == 'pull_request'
41+
run: |
42+
npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }}
43+
44+
- name: Type check
45+
run: npx tsc --noEmit
46+
47+
- name: Run tests with coverage
48+
run: yarn test:ci
49+
50+
- name: Upload coverage reports
51+
if: matrix.node-version == '20'
52+
uses: codecov/codecov-action@v4
53+
with:
54+
token: ${{ secrets.CODECOV_TOKEN }}
55+
files: ./coverage/coverage-final.json
56+
flags: unittests
57+
name: codecov-umbrella
58+
59+
- name: Build
60+
run: yarn build
61+
62+
- name: Upload build artifacts
63+
uses: actions/upload-artifact@v4
64+
with:
65+
name: dist-node-${{ matrix.node-version }}
66+
path: dist/
67+
retention-days: 7

.github/workflows/release.yml

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
contents: write
10+
packages: write
11+
id-token: write
12+
attestations: write
13+
14+
jobs:
15+
release:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
22+
23+
- name: Setup Node.js
24+
uses: actions/setup-node@v4
25+
with:
26+
node-version: '20'
27+
registry-url: 'https://registry.npmjs.org'
28+
29+
- name: Enable Corepack
30+
run: corepack enable
31+
32+
- name: Install dependencies
33+
run: yarn install --frozen-lockfile
34+
35+
- name: Run tests
36+
run: yarn test
37+
38+
- name: Build
39+
run: yarn build
40+
41+
- name: Generate SBOM
42+
uses: anchore/sbom-action@v0
43+
with:
44+
format: spdx-json
45+
output-file: sbom.spdx.json
46+
47+
- name: Attest Build Provenance
48+
uses: actions/attest-build-provenance@v1
49+
with:
50+
subject-path: |
51+
./dist
52+
./sbom.spdx.json
53+
54+
- name: Attest SBOM
55+
uses: actions/attest-sbom@v1
56+
with:
57+
subject-path: './dist'
58+
sbom-path: './sbom.spdx.json'
59+
60+
- name: Generate Release Notes
61+
id: changelog
62+
run: |
63+
# Extract version changelog
64+
VERSION=${GITHUB_REF#refs/tags/}
65+
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
66+
67+
# Extract changelog for this version
68+
if [ -f "CHANGELOG.md" ]; then
69+
CHANGELOG=$(awk -v ver="$VERSION" '
70+
/^##? \[?v?[0-9]+\.[0-9]+\.[0-9]+/ {
71+
if (p) exit;
72+
if ($0 ~ ver) p=1;
73+
next;
74+
}
75+
p && /^##? \[?v?[0-9]+\.[0-9]+\.[0-9]+/ {exit}
76+
p {print}
77+
' CHANGELOG.md)
78+
79+
echo "CHANGELOG<<EOF" >> $GITHUB_OUTPUT
80+
echo "$CHANGELOG" >> $GITHUB_OUTPUT
81+
echo "EOF" >> $GITHUB_OUTPUT
82+
else
83+
echo "CHANGELOG=No changelog found" >> $GITHUB_OUTPUT
84+
fi
85+
86+
- name: Create GitHub Release
87+
uses: softprops/action-gh-release@v1
88+
with:
89+
name: Release ${{ steps.changelog.outputs.VERSION }}
90+
body: |
91+
## What's Changed
92+
${{ steps.changelog.outputs.CHANGELOG }}
93+
94+
## Attestations
95+
This release includes build provenance attestation and SBOM (Software Bill of Materials).
96+
97+
You can verify the attestation using:
98+
```bash
99+
gh attestation verify <artifact> --owner ${{ github.repository_owner }}
100+
```
101+
files: |
102+
sbom.spdx.json
103+
generate_release_notes: true
104+
105+
- name: Publish to NPM
106+
run: npm publish --access public --provenance
107+
env:
108+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
109+
110+
- name: Setup Node.js for GitHub Packages
111+
uses: actions/setup-node@v4
112+
with:
113+
registry-url: 'https://npm.pkg.github.com'
114+
scope: '@${{ github.repository_owner }}'
115+
116+
- name: Publish to GitHub Packages
117+
run: |
118+
# Update package name for GitHub Packages
119+
npm pkg set name="@${{ github.repository_owner }}/mcp-wayback-machine"
120+
npm publish --access public --provenance
121+
env:
122+
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
name: Semantic Release
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
permissions:
9+
contents: write
10+
packages: write
11+
id-token: write
12+
attestations: write
13+
issues: write
14+
pull-requests: write
15+
16+
jobs:
17+
release:
18+
runs-on: ubuntu-latest
19+
if: "!contains(github.event.head_commit.message, '[skip ci]')"
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@v4
23+
with:
24+
fetch-depth: 0
25+
token: ${{ secrets.GITHUB_TOKEN }}
26+
27+
- name: Setup Node.js
28+
uses: actions/setup-node@v4
29+
with:
30+
node-version: '20'
31+
registry-url: 'https://registry.npmjs.org'
32+
33+
- name: Enable Corepack
34+
run: corepack enable
35+
36+
- name: Install dependencies
37+
run: yarn install --frozen-lockfile
38+
39+
- name: Run tests
40+
run: yarn test
41+
42+
- name: Build
43+
run: yarn build
44+
45+
- name: Run semantic-release
46+
id: semantic-release
47+
env:
48+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
49+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
50+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
51+
run: |
52+
# Capture the current version before release
53+
CURRENT_VERSION=$(node -p "require('./package.json').version")
54+
55+
# Run semantic-release
56+
npx semantic-release
57+
58+
# Check if version changed (indicating a release was made)
59+
NEW_VERSION=$(node -p "require('./package.json').version")
60+
if [ "$CURRENT_VERSION" != "$NEW_VERSION" ]; then
61+
echo "new-release-published=true" >> $GITHUB_OUTPUT
62+
echo "new-version=$NEW_VERSION" >> $GITHUB_OUTPUT
63+
else
64+
echo "new-release-published=false" >> $GITHUB_OUTPUT
65+
fi
66+
67+
- name: Generate SBOM
68+
if: steps.semantic-release.outputs.new-release-published == 'true'
69+
uses: anchore/sbom-action@v0
70+
with:
71+
format: spdx-json
72+
output-file: sbom.spdx.json
73+
74+
- name: Attest Build Provenance
75+
if: steps.semantic-release.outputs.new-release-published == 'true'
76+
uses: actions/attest-build-provenance@v1
77+
with:
78+
subject-path: |
79+
./dist
80+
./sbom.spdx.json
81+
82+
- name: Attest SBOM
83+
if: steps.semantic-release.outputs.new-release-published == 'true'
84+
uses: actions/attest-sbom@v1
85+
with:
86+
subject-path: './dist'
87+
sbom-path: './sbom.spdx.json'
88+
89+
- name: Setup Node.js for GitHub Packages
90+
if: steps.semantic-release.outputs.new-release-published == 'true'
91+
uses: actions/setup-node@v4
92+
with:
93+
registry-url: 'https://npm.pkg.github.com'
94+
scope: '@${{ github.repository_owner }}'
95+
96+
- name: Publish to GitHub Packages
97+
if: steps.semantic-release.outputs.new-release-published == 'true'
98+
run: |
99+
# Update package name for GitHub Packages (must be lowercase)
100+
npm pkg set name="@mearman/mcp-wayback-machine"
101+
# Ensure we're publishing to GitHub Packages registry
102+
npm config set registry https://npm.pkg.github.com/
103+
# Skip prepublishOnly script to avoid running tests with modified package name
104+
npm publish --access public --provenance --ignore-scripts
105+
env:
106+
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)