Skip to content

Commit 6e2d8e6

Browse files
committed
feat: add CI/CD workflows and version check script
1 parent 5577df3 commit 6e2d8e6

File tree

5 files changed

+149
-0
lines changed

5 files changed

+149
-0
lines changed

.github/workflows/cd.yaml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: CD
2+
3+
on:
4+
push:
5+
branches: [ "main" ]
6+
workflow_dispatch:
7+
8+
concurrency:
9+
group: "publish"
10+
cancel-in-progress: true
11+
12+
jobs:
13+
check-version:
14+
runs-on: ubuntu-latest
15+
outputs:
16+
should_publish: ${{ steps.check-version.outputs.local_version_is_higher }}
17+
tag: ${{ steps.check-version.outputs.tag }}
18+
version: ${{ steps.check-version.outputs.local_version }}
19+
steps:
20+
- uses: actions/checkout@v4
21+
- uses: actions/setup-node@v4
22+
with:
23+
node-version: "24"
24+
- uses: pnpm/action-setup@v4
25+
- run: pnpm install
26+
- id: check-version
27+
run: pnpm exec tsx bin/check-version.ts
28+
29+
publish:
30+
needs: check-version
31+
if: needs.check-version.outputs.should_publish == 'true'
32+
runs-on: ubuntu-latest
33+
steps:
34+
- uses: actions/checkout@v4
35+
- uses: actions/setup-node@v4
36+
with:
37+
node-version: "23"
38+
registry-url: "https://registry.npmjs.org"
39+
- uses: pnpm/action-setup@v4
40+
- run: pnpm install
41+
- run: pnpm build
42+
- run: pnpm exec biome ci
43+
- run: tsc
44+
- env:
45+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
46+
run: pnpm publish --tag ${{ needs.check-version.outputs.tag }} --no-git-checks

.github/workflows/ci.yaml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: CI
2+
3+
on: [push, pull_request]
4+
5+
concurrency:
6+
group: ${{ github.workflow }}-${{ github.ref }}
7+
cancel-in-progress: true
8+
9+
jobs:
10+
check:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
- uses: actions/setup-node@v4
15+
with:
16+
node-version: "23"
17+
- uses: pnpm/action-setup@v4
18+
- run: pnpm install
19+
- run: pnpm build
20+
- run: pnpm exec biome ci
21+
- run: tsc
22+
23+
test:
24+
needs: check
25+
runs-on: ubuntu-latest
26+
steps:
27+
- uses: actions/checkout@v4
28+
- uses: actions/setup-node@v4
29+
with:
30+
node-version: "23"
31+
- uses: pnpm/action-setup@v4
32+
- run: pnpm install
33+
- run: pnpm vitest --coverage
34+
- uses: davelosert/vitest-coverage-report-action@v2
35+
if: always()
36+
with:
37+
comment-on: "pr"

bin/check-version.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/usr/bin/env tsx
2+
3+
import { appendFileSync } from "node:fs";
4+
import semver from "semver";
5+
import packageJson from "../package.json";
6+
7+
interface NpmRegistryResponse {
8+
"dist-tags": Record<string, string>;
9+
}
10+
11+
async function getNpmVersion(
12+
packageName: string,
13+
distTag: string,
14+
): Promise<string> {
15+
const response = await fetch(`https://registry.npmjs.org/${packageName}`);
16+
if (response.ok) {
17+
const data = (await response.json()) as NpmRegistryResponse;
18+
return data["dist-tags"][distTag] || "0.0.0";
19+
}
20+
return "0.0.0";
21+
}
22+
23+
function writeGitHubOutput(key: string, value: string): void {
24+
const githubOutput = process.env.GITHUB_OUTPUT;
25+
if (githubOutput) {
26+
appendFileSync(githubOutput, `${key}=${value}\n`);
27+
}
28+
console.log(`${key}=${value}`);
29+
}
30+
31+
async function main(): Promise<void> {
32+
// Validate version format
33+
if (!semver.valid(packageJson.version)) {
34+
throw new Error(`Invalid version format: ${packageJson.version}`);
35+
}
36+
37+
// Determine tag based on pre-release status
38+
const distTag = semver.prerelease(packageJson.version) ? "next" : "latest";
39+
const localVersion = packageJson.version;
40+
const publicVersion = await getNpmVersion(packageJson.name, distTag);
41+
const localVersionIsHigher = semver.gt(localVersion, publicVersion);
42+
43+
// Write outputs
44+
writeGitHubOutput("local_version_is_higher", localVersionIsHigher.toString());
45+
writeGitHubOutput("local_version", localVersion);
46+
writeGitHubOutput("published_version", publicVersion);
47+
writeGitHubOutput("tag", distTag);
48+
}
49+
50+
// E.g. if this file is the entry point
51+
if (import.meta.url === `file://${process.argv[1]}`) {
52+
main().catch(console.error);
53+
}

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
"@biomejs/biome": "2.3.5",
3535
"@nillion/nuc": "link:../nuc-ts",
3636
"@types/node": "^24.10.1",
37+
"@types/semver": "^7.7.1",
3738
"pino": "^10.1.0",
39+
"semver": "^7.7.3",
3840
"tsdown": "^0.16.8",
3941
"tsx": "^4.21.0",
4042
"typescript": "^5.9.3",

pnpm-lock.yaml

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)