From 2a5b0b98f429f7a68c268f5c4d111dafbf83d55c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=BCger?= Date: Sun, 16 Aug 2026 13:55:47 +0200 Subject: [PATCH] Add a Gitea Actions release workflow: lint/typecheck/format check -> build -> publish Triggered on tags matching v*.*.* - runs the quality gate (lint, typecheck, format:check, the existing test suite, build) as individual steps for clear failure attribution, then publishes to this Gitea instance's own npm registry (dev.pivoine.art, unscoped package name - Gitea's npm registry supports that directly, no @owner/ rename needed). The release version comes from the git tag (v1.0.0 -> 1.0.0 via `npm pkg set`), patched into package.json only in the CI run, never committed back. publishConfig.registry in package.json is a static string (safe to commit); the auth token is supplied at publish time via NODE_AUTH_TOKEN, written to a CI-generated user-level .npmrc by actions/setup-node's registry-url option rather than a repo-committed one - pnpm >=10.34.2/11.5.3 (this repo pins 11.21.0) blocks ${VAR} expansion in repository-controlled npmrc/pnpm-workspace.yaml specifically to stop a malicious repo from exfiltrating CI secrets that way, so the token can't live in a committed .npmrc at all. Verified locally end-to-end short of the actual registry upload: lint/typecheck/format:check/test/build all pass, and `pnpm publish --dry-run --no-git-checks` after a temporary version bump confirms publishConfig.registry resolves to the right URL and prepack (next build) fires automatically as part of publish. One-time manual setup this can't do by itself (documented in the plan file): a repo-scoped Gitea Personal Access Token with the `package` Read&Write scope, stored as the GITEA_PACKAGE_TOKEN repo secret - Gitea's own auto-injected GITEA_TOKEN explicitly cannot publish packages (unimplemented per Gitea's own docs). Co-Authored-By: Claude Sonnet 5 --- .gitea/workflows/release.yaml | 38 +++++++++++++++++++++++++++++++++++ package.json | 4 ++++ 2 files changed, 42 insertions(+) create mode 100644 .gitea/workflows/release.yaml diff --git a/.gitea/workflows/release.yaml b/.gitea/workflows/release.yaml new file mode 100644 index 0000000..34af012 --- /dev/null +++ b/.gitea/workflows/release.yaml @@ -0,0 +1,38 @@ +name: Release + +on: + push: + tags: + - "v*.*.*" + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: https://github.com/actions/checkout@v4 + + - uses: https://github.com/pnpm/action-setup@v4 + with: + version: 11.21.0 + + - uses: https://github.com/actions/setup-node@v4 + with: + node-version: 20 + cache: pnpm + registry-url: https://dev.pivoine.art/api/packages/valknar/npm/ + + - run: pnpm install --frozen-lockfile + + - run: pnpm run lint + - run: pnpm run typecheck + - run: pnpm run format:check + - run: pnpm run test + - run: pnpm run build + + - name: Set package version from the tag + run: npm pkg set version="${GITHUB_REF_NAME#v}" + + - name: Publish to Gitea npm registry + run: pnpm publish --no-git-checks + env: + NODE_AUTH_TOKEN: ${{ secrets.GITEA_PACKAGE_TOKEN }} diff --git a/package.json b/package.json index 068e15f..39f950f 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,9 @@ "engines": { "node": ">=20" }, + "publishConfig": { + "registry": "https://dev.pivoine.art/api/packages/valknar/npm/" + }, "files": [ "bin", "src", @@ -33,6 +36,7 @@ "lint": "eslint", "typecheck": "tsc --noEmit", "format": "prettier --write .", + "format:check": "prettier --check .", "test": "tsx --test \"src/cli/**/*.test.ts\"", "db:generate": "drizzle-kit generate", "db:studio": "drizzle-kit studio",