From 3a3e48490811d4bbd00290f31ec9bbf6a0d25d0b Mon Sep 17 00:00:00 2001 From: pbio <10051819+paulbalaji@users.noreply.github.com> Date: Wed, 26 Nov 2025 13:38:50 +0000 Subject: [PATCH 1/2] feat: add NPM preview release workflow and fix CI permissions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds several improvements to the release workflows: 1. **NPM Preview Release Workflow** (`.github/workflows/npm-preview-release.yml`) - Manual dispatch workflow to publish NPM packages as preview releases - Supports beta, alpha, rc, and preview dist-tags - Version format: `{baseVersion}-{tag}.{gitSha}` (e.g., `19.10.0-beta.abc1234`) - Creates GitHub pre-release with installation instructions - Can be triggered from any branch 2. **Changeset Snapshot Configuration** (`.changeset/config.json`) - Added `snapshot` config for preview release versioning - Uses `{tag}.{commit}` format for prerelease identifiers 3. **CI Permissions Fix** (`.github/workflows/release.yml`) - Uses GitHub App token instead of GITHUB_TOKEN - Fixes issue where CI wouldn't trigger on changesets PRs - Added `title` override to pass PR title lint ("chore: release npm packages") 4. **CI Permissions Fix** (`.github/workflows/rust-release.yml`) - Uses GitHub App token instead of GITHUB_TOKEN - Fixes issue where CI wouldn't trigger on release PRs **Setup Required:** Create a GitHub App with the following: - Permissions: Contents (read/write), Pull requests (read/write) - Install the app on this repository - Add these secrets: - `HYPERLANE_GITHUB_APP_ID`: The App ID - `HYPERLANE_GITHUB_APP_PRIVATE_KEY`: The private key 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .changeset/config.json | 6 +- .github/workflows/npm-preview-release.yml | 112 ++++++++++++++++++++++ .github/workflows/release.yml | 20 +++- .github/workflows/rust-release.yml | 8 +- 4 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/npm-preview-release.yml diff --git a/.changeset/config.json b/.changeset/config.json index a01341a4efa..cdc4180d3e9 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -30,5 +30,9 @@ "access": "public", "baseBranch": "main", "updateInternalDependencies": "patch", - "ignore": [] + "ignore": [], + "snapshot": { + "useCalculatedVersion": true, + "prereleaseTemplate": "{tag}.{commit}" + } } diff --git a/.github/workflows/npm-preview-release.yml b/.github/workflows/npm-preview-release.yml new file mode 100644 index 00000000000..3ae56982b5f --- /dev/null +++ b/.github/workflows/npm-preview-release.yml @@ -0,0 +1,112 @@ +name: NPM Preview Release + +on: + workflow_dispatch: + inputs: + snapshot_tag: + description: 'NPM dist-tag for the preview release' + required: true + default: 'beta' + type: choice + options: + - beta + - alpha + - rc + - preview + +concurrency: + group: npm-preview-release + cancel-in-progress: false + +env: + LOG_FORMAT: PRETTY + TURBO_TELEMETRY_DISABLED: 1 + TURBO_API: https://cache.depot.dev + TURBO_TOKEN: ${{ secrets.DEPOT_TURBO_TOKEN }} + TURBO_TEAM: ${{ secrets.DEPOT_ORG_ID }} + +jobs: + preview-release: + runs-on: depot-ubuntu-latest + permissions: + id-token: write + contents: write + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + fetch-depth: 0 + submodules: recursive + + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version-file: .nvmrc + registry-url: 'https://registry.npmjs.org' + + - name: Get short SHA + id: sha + run: echo "short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + + - name: Get base version + id: version + run: | + BASE_VERSION=$(node -p "require('./typescript/sdk/package.json').version") + PREVIEW_VERSION="${BASE_VERSION}-${{ inputs.snapshot_tag }}.${{ steps.sha.outputs.short }}" + echo "base=$BASE_VERSION" >> $GITHUB_OUTPUT + echo "preview=$PREVIEW_VERSION" >> $GITHUB_OUTPUT + + - name: Install dependencies + run: yarn install --immutable + + - name: Create snapshot versions + run: yarn changeset version --snapshot ${{ inputs.snapshot_tag }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Build packages + run: yarn build + + - name: Publish preview packages + run: yarn changeset publish --tag ${{ inputs.snapshot_tag }} + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + NPM_CONFIG_PROVENANCE: true + + - name: Create GitHub Pre-release + uses: softprops/action-gh-release@v2 + with: + tag_name: v${{ steps.version.outputs.preview }} + name: v${{ steps.version.outputs.preview }} + target_commitish: ${{ github.sha }} + prerelease: true + generate_release_notes: true + body: | + > [!WARNING] + > This is a preview release for testing purposes. Do not use in production. + + **Branch:** `${{ github.ref_name }}` + **Commit:** ${{ github.sha }} + + ## Installation + ```bash + npm install @hyperlane-xyz/sdk@${{ inputs.snapshot_tag }} + npm install @hyperlane-xyz/cli@${{ inputs.snapshot_tag }} + ``` + + ## Packages Published + All packages in the fixed group were published with version `${{ steps.version.outputs.preview }}` + + - name: Summary + run: | + echo "### Preview Release Published" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Version:** \`${{ steps.version.outputs.preview }}\`" >> $GITHUB_STEP_SUMMARY + echo "**NPM Tag:** \`${{ inputs.snapshot_tag }}\`" >> $GITHUB_STEP_SUMMARY + echo "**Branch:** \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "Install with:" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY + echo "npm install @hyperlane-xyz/sdk@${{ inputs.snapshot_tag }}" >> $GITHUB_STEP_SUMMARY + echo "npm install @hyperlane-xyz/cli@${{ inputs.snapshot_tag }}" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1ec77b87401..dcb4abd2ba1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -55,14 +55,22 @@ jobs: - name: Install Dependencies run: yarn install --immutable + - name: Generate GitHub App Token + id: generate-token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ secrets.HYPER_GONK_APP_ID }} + private-key: ${{ secrets.HYPER_GONK_PRIVATE_KEY }} + - name: Create Release PR id: changesets uses: changesets/action@v1 with: version: yarn version:prepare + title: 'chore: release npm packages' env: NPM_CONFIG_PROVENANCE: true - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} check-latest-published: @@ -150,13 +158,21 @@ jobs: - name: Install Dependencies run: yarn install --immutable + - name: Generate GitHub App Token + id: generate-token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ secrets.HYPER_GONK_APP_ID }} + private-key: ${{ secrets.HYPER_GONK_PRIVATE_KEY }} + - name: Publish Release to NPM id: changesets uses: changesets/action@v1 with: version: yarn version:prepare publish: yarn release + title: 'chore: release npm packages' env: NPM_CONFIG_PROVENANCE: true - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml index be45fcc0cfe..b8e905c5b16 100644 --- a/.github/workflows/rust-release.yml +++ b/.github/workflows/rust-release.yml @@ -170,9 +170,15 @@ jobs: cd ../sealevel cargo update --workspace --offline 2>/dev/null || cargo update --workspace echo "Updated rust/sealevel/Cargo.lock" + - name: Generate GitHub App Token + id: generate-token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ secrets.HYPER_GONK_APP_ID }} + private-key: ${{ secrets.HYPER_GONK_PRIVATE_KEY }} - name: Create or update release PR env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} NEW_VERSION: ${{ steps.next_version.outputs.new_version }} BUMP_TYPE: ${{ steps.next_version.outputs.bump_type }} CHANGELOG: ${{ steps.changelog.outputs.changelog }} From 1509e6faa426e6f53f7b9facd072a263683c159a Mon Sep 17 00:00:00 2001 From: pbio <10051819+paulbalaji@users.noreply.github.com> Date: Wed, 26 Nov 2025 15:17:51 +0000 Subject: [PATCH 2/2] fix: use calculated next version for Rust prereleases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This aligns the Rust prerelease versioning with NPM's behavior. Previously: 1.7.0 -> 1.7.0-preview.1 Now: 1.7.0 -> 1.8.0-preview.1 (uses next calculated version) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .github/workflows/rust-release.yml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml index b8e905c5b16..b2c99234fd4 100644 --- a/.github/workflows/rust-release.yml +++ b/.github/workflows/rust-release.yml @@ -285,12 +285,19 @@ jobs: # Determine final version based on release type # workflow_dispatch always creates pre-releases if [ "$IS_PRERELEASE" = "true" ]; then - # Pre-release: append suffix + # For prereleases, calculate the next version (like changesets does for NPM) + # This ensures prerelease versions reflect what the next release will be + # e.g., if current is 1.7.0, prerelease will be 1.8.0-preview.1 (not 1.7.0-preview.1) + OUTPUT=$(./rust/scripts/ci/determine-next-version.sh "$BASE_VERSION") + NEXT_VERSION=$(echo "$OUTPUT" | sed -n '1p') + echo "Calculated next version: $NEXT_VERSION (from base $BASE_VERSION)" + + # Pre-release: append suffix to the NEXT version if [ -n "$PRERELEASE_SUFFIX" ]; then SUFFIX="$PRERELEASE_SUFFIX" else # Auto-generate preview.N - LAST_PREVIEW=$(git tag -l "agents-v${BASE_VERSION}-preview.*" | sort -V | tail -1) + LAST_PREVIEW=$(git tag -l "agents-v${NEXT_VERSION}-preview.*" | sort -V | tail -1) if [ -z "$LAST_PREVIEW" ]; then SUFFIX="preview.1" else @@ -298,7 +305,7 @@ jobs: SUFFIX="preview.$((PREVIEW_NUM + 1))" fi fi - VERSION="${BASE_VERSION}-${SUFFIX}" + VERSION="${NEXT_VERSION}-${SUFFIX}" TITLE="Agents $VERSION (Pre-release)" PRERELEASE_FLAG="--prerelease" RELEASE_TYPE="Pre-release"