From 37e3cdc057c73ff75e2f0e986a9664737c1a5e98 Mon Sep 17 00:00:00 2001 From: sepehr-safari Date: Tue, 7 Jul 2026 23:07:35 +0300 Subject: [PATCH] chore: add CI workflow + changesets release infrastructure - .github/workflows/ci.yml: lint, format check, typecheck, test, build on push to main and PRs to main. Node 22, pnpm cached, frozen lockfile. Least-privilege permissions (contents: read), concurrency cancellation. - .github/workflows/release.yml: Changesets version PR + npm publish + ecosystem tag (release-v0.x.0) + GitHub release. Only fires when version PR is merged. Separate contents:write/pull-requests:write permissions scoped to release job only. - .changeset/config.json: public access, base branch main Closes #5, closes #6 --- .changeset/config.json | 11 +++++ .github/workflows/ci.yml | 53 +++++++++++++++++++++++ .github/workflows/release.yml | 81 +++++++++++++++++++++++++++++++++++ CURRENT_STATE.md | 14 +++--- 4 files changed, 152 insertions(+), 7 deletions(-) create mode 100644 .changeset/config.json create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release.yml diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..fce1c26 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..71245bf --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,53 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +permissions: + contents: read + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + ci: + name: Lint, Typecheck, Test, Build + runs-on: ubuntu-latest + timeout-minutes: 15 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Lint + run: pnpm lint + + - name: Format check + run: pnpm format:check + + - name: Typecheck + run: pnpm typecheck + + - name: Test + run: pnpm test + + - name: Build + run: pnpm build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..010cde4 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,81 @@ +name: Release + +on: + push: + branches: [main] + +permissions: + contents: read + +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: false + +jobs: + release: + name: Version, Publish, Tag & Release + runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + contents: write + pull-requests: write + id-token: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + registry-url: https://registry.npmjs.org + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Create release PR or publish + id: changesets + uses: changesets/action@v1 + with: + publish: pnpm changeset publish + version: pnpm changeset version + title: 'chore: version packages' + commit: 'chore: version packages' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Create ecosystem tag and GitHub release + if: steps.changesets.outputs.published == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + # Determine the ecosystem tag from the latest published version + LATEST_TAG="" + for pkg in packages/*/; do + if [ -f "$pkg/package.json" ]; then + VERSION=$(node -p "require('./$pkg/package.json').version" 2>/dev/null || echo "") + if [ -n "$VERSION" ]; then + # Extract major.minor for ecosystem tag (e.g. 0.1.0 -> v0.1.0) + TAG="release-v$(echo "$VERSION" | cut -d. -f1-2).0" + LATEST_TAG="$TAG" + fi + fi + done + + if [ -n "$LATEST_TAG" ] && ! gh release view "$LATEST_TAG" >/dev/null 2>&1; then + echo "Creating GitHub release: $LATEST_TAG" + gh release create "$LATEST_TAG" \ + --title "$LATEST_TAG" \ + --notes-from-tag \ + --generate-notes + else + echo "Tag $LATEST_TAG already exists or no packages published" + fi diff --git a/CURRENT_STATE.md b/CURRENT_STATE.md index a61f30a..afa83ab 100644 --- a/CURRENT_STATE.md +++ b/CURRENT_STATE.md @@ -32,16 +32,16 @@ feature code lands. - ✅ `NOTICE` file (Apache 2.0) - ✅ `AGENTS.md` + `CURRENT_STATE.md` (initial versions) -## What's In Progress - -- **PR #12** (this PR): Monorepo + tooling foundation (Issues #1–#4) +### CI & Release (in progress — this PR) +- ✅ `.github/workflows/ci.yml` — lint, format check, typecheck, test, build on PR + push +- ✅ `.github/workflows/release.yml` — Changesets version PR, npm publish, ecosystem tag + GitHub release +- ✅ `.changeset/config.json` — public access, base branch main ## What's Next -1. **PR2** (Issues #5–#6): GitHub Actions CI workflow + Changesets/release workflow -2. **PR3** (Issues #7–#8): PR template + issue templates -3. **PR4** (Issues #9–#11): CONTRIBUTING, CODE_OF_CONDUCT, ROADMAP, README -4. **M0 complete** → proceed to M0.5 (Protocol & Trace-Format Design Phase) +1. **PR3** (Issues #7–#8): PR template + issue templates +2. **PR4** (Issues #9–#11): CONTRIBUTING, CODE_OF_CONDUCT, ROADMAP, README +3. **M0 complete** → proceed to M0.5 (Protocol & Trace-Format Design Phase) ## Known Blockers / Decisions Pending