diff --git a/.github/DISCUSSION_TEMPLATE/idea.yml b/.github/DISCUSSION_TEMPLATE/idea.yml new file mode 100644 index 0000000..4f2f798 --- /dev/null +++ b/.github/DISCUSSION_TEMPLATE/idea.yml @@ -0,0 +1,21 @@ +title: Idea / Proposal +labels: ["idea"] + +body: + - type: textarea + attributes: + label: Describe the idea + validations: + required: true + + - type: textarea + attributes: + label: Problem Statement + + - type: textarea + attributes: + label: Proposed Solution + + - type: textarea + attributes: + label: Impact diff --git a/.github/DISCUSSION_TEMPLATE/support.yml b/.github/DISCUSSION_TEMPLATE/support.yml new file mode 100644 index 0000000..1e46ab3 --- /dev/null +++ b/.github/DISCUSSION_TEMPLATE/support.yml @@ -0,0 +1,20 @@ +title: Support / Question +labels: ["question"] + +body: + - type: textarea + attributes: + label: Describe your issue / question + validations: + required: true + + - type: textarea + attributes: + label: Additional Details + + - type: checkboxes + attributes: + label: Checklist + options: + - label: I have checked existing issues/discussions + required: true diff --git a/.github/workflows/ci.yml b/.github/workflows/pr-check.yml similarity index 81% rename from .github/workflows/ci.yml rename to .github/workflows/pr-check.yml index 3146190..0aa74cc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/pr-check.yml @@ -1,22 +1,29 @@ -name: CI +name: PR Merge Check - Codeoid on: - push: - branches: [main] pull_request: - branches: [main] + types: + - opened + - synchronize + - reopened + branches: + - "main" + merge_group: + types: + - checks_requested -# Cancel superseded runs on the same branch/PR. concurrency: - group: ci-${{ github.ref }} + group: ${{ github.workflow }}-${{ github.head_ref }} cancel-in-progress: true jobs: - daemon: - name: daemon + daemon-check: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v6 + with: + persist-credentials: false - name: Setup Bun uses: oven-sh/setup-bun@v2 @@ -29,8 +36,6 @@ jobs: - name: Lint run: bun run lint - # Catch npm-version drift between the CLI and its workspace packages on - # the PR, not at tag time when the release is already in flight. - name: Version lockstep run: bun run check:versions @@ -60,14 +65,16 @@ jobs: - name: Build run: bun run build - web: - name: web + web-check: runs-on: ubuntu-24.04 defaults: run: working-directory: web steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v6 + with: + persist-credentials: false - name: Setup Bun uses: oven-sh/setup-bun@v2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 68a0297..c065602 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,19 +1,92 @@ -name: Release +name: Release Build - Codeoid on: - push: - tags: ["v*"] + release: + types: + - published +<<<<<<< Updated upstream permissions: contents: write # create the GitHub Release id-token: write # npm OIDC Trusted Publishing + provenance +======= +env: + REGEX_PATTERN: "^v[0-9]+\\.[0-9]+\\.[0-9]+$" +>>>>>>> Stashed changes jobs: - npm: - name: Publish to npm + highflame-validate: + permissions: + contents: 'read' runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v6 + with: + fetch-depth: 0 + persist-credentials: true + + - name: Validate Release Tag + id: validate_tag + shell: bash + run: |- + if [[ "${{ env.RELEASE_TAG }}" =~ ${{ env.REGEX_PATTERN }} ]] ; then + echo "Valid version format: ${{ env.RELEASE_TAG }}" + else + echo "Invalid version format: ${{ env.RELEASE_TAG }}" + exit 1 + fi + + highflame-release: + needs: + - highflame-validate + permissions: + contents: write + id-token: write + runs-on: ubuntu-24.04 + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + persist-credentials: false + + - name: Extract version from release + id: version + env: + RELEASE_NAME: ${{ github.event.release.name }} + run: |- + VERSION=$(echo "$RELEASE_NAME" | sed 's|^v||g') + echo "VERSION=$VERSION" >> $GITHUB_OUTPUT + echo "Releasing version: $VERSION" + + - name: Update root package.json + env: + VERSION: ${{ steps.version.outputs.VERSION }} + run: |- + jq ".version = \"${VERSION}\"" package.json > package.json.tmp + mv package.json.tmp package.json + echo "Updated root package.json:" + grep '"version"' package.json + + - name: Update protocol package.json + env: + VERSION: ${{ steps.version.outputs.VERSION }} + run: |- + cd packages/protocol + jq ".version = \"${VERSION}\"" package.json > package.json.tmp + mv package.json.tmp package.json + echo "Updated protocol package.json:" + grep '"version"' package.json + + - name: Update core package.json + env: + VERSION: ${{ steps.version.outputs.VERSION }} + run: |- + cd packages/core + jq ".version = \"${VERSION}\"" package.json > package.json.tmp + mv package.json.tmp package.json + echo "Updated core package.json:" + grep '"version"' package.json - name: Setup Bun uses: oven-sh/setup-bun@v2 @@ -41,11 +114,15 @@ jobs: run: bun run check:versions "${GITHUB_REF_NAME}" - name: Build web UI - run: cd web && bun install --frozen-lockfile && bun run build + run: |- + cd web + bun install --frozen-lockfile + bun run build - name: Test run: bun run test +<<<<<<< Updated upstream # Publish order is dependency order: protocol → core → the CLI, so each # tarball's declared deps are resolvable on the registry the moment it # lands. No NODE_AUTH_TOKEN anywhere — auth is the GitHub OIDC id-token @@ -80,3 +157,48 @@ jobs: uses: softprops/action-gh-release@v2 with: generate_release_notes: true +======= + - name: Verify package version matches the tag + run: |- + PKG="$(node -p "require('./package.json').version")" + TAG="${GITHUB_REF_NAME#v}" + if [ "$PKG" != "$TAG" ]; then + echo "::error::package.json version ($PKG) does not match tag ($TAG)" + exit 1 + fi + + # @highflame/codeoid-protocol is a workspace dependency of codeoid; publish it FIRST + # (only when its version is new) so codeoid's published dep resolves. + # NOTE: requires a separate npm Trusted Publisher configured for + # @highflame/codeoid-protocol at npmjs.com (same OIDC setup as codeoid) before the + # first release that introduces a new protocol version. + - name: Publish @highflame/codeoid-protocol (OIDC) — only if version is new + run: | + cd packages/protocol + VER="$(node -p "require('./package.json').version")" + if npm view "@highflame/codeoid-protocol@$VER" version >/dev/null 2>&1; then + echo "@highflame/codeoid-protocol@$VER already published — skipping" + else + npm publish + fi + + # @highflame/codeoid-core (client transport + store semantics — consumed by the + # mobile app from the registry; web uses the in-repo copy). Publishes + # after protocol (its peer dep) and needs its own Trusted Publisher + + # one-time manual bootstrap publish, same as protocol. + - name: Publish @highflame/codeoid-core (OIDC) — only if version is new + run: | + cd packages/core + VER="$(node -p "require('./package.json').version")" + if npm view "@highflame/codeoid-core@$VER" version >/dev/null 2>&1; then + echo "@highflame/codeoid-core@$VER already published — skipping" + else + npm publish + fi + + # No NODE_AUTH_TOKEN: auth comes from the GitHub OIDC id-token via npm's + # Trusted Publisher (configured on the package at npmjs.com). Provenance + # is generated automatically from the same OIDC identity. + - name: Publish codeoid to npm (OIDC Trusted Publishing) + run: npm publish +>>>>>>> Stashed changes