From 80cfdb51e922882bfad8189b3413cb44e80e6ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 8 May 2026 22:53:28 +0200 Subject: [PATCH 1/2] Add release-prepare workflow Manually-triggered workflow that bumps the version across the three @fluffylabs/jammin* package.json files, opens a PR against main, and creates a draft GitHub release. Once the maintainer merges the PR and publishes the draft release, the existing publish-npm-{cli,sdk} workflows fire on `release: published` and ship the artifacts to npm. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/release-prepare.yml | 141 ++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 .github/workflows/release-prepare.yml diff --git a/.github/workflows/release-prepare.yml b/.github/workflows/release-prepare.yml new file mode 100644 index 0000000..3019367 --- /dev/null +++ b/.github/workflows/release-prepare.yml @@ -0,0 +1,141 @@ +name: Prepare release + +on: + workflow_dispatch: + inputs: + version: + description: "Target version (semver, with or without v prefix). Pre-releases like 0.2.0-rc.1 are allowed." + required: true + type: string + +permissions: + contents: write + pull-requests: write + +concurrency: + group: release-prepare + cancel-in-progress: false + +env: + BUN_VERSION: 1.3.3 + +jobs: + prepare: + runs-on: ubuntu-latest + steps: + - name: Checkout main + uses: actions/checkout@v4 + with: + ref: main + fetch-depth: 0 + + - name: Setup Bun + uses: oven-sh/setup-bun@v1 + with: + bun-version: ${{ env.BUN_VERSION }} + + - name: Validate and normalize version + id: ver + env: + INPUT_VERSION: ${{ inputs.version }} + run: | + VERSION="${INPUT_VERSION#v}" + SEMVER_REGEX='^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\+([0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*))?$' + if [[ ! "$VERSION" =~ $SEMVER_REGEX ]]; then + echo "Error: '$INPUT_VERSION' is not a valid semver version" >&2 + exit 1 + fi + TAG="v${VERSION}" + BRANCH="release/${TAG}" + { + echo "version=${VERSION}" + echo "tag=${TAG}" + echo "branch=${BRANCH}" + } >> "$GITHUB_OUTPUT" + echo "Normalized: tag=${TAG}, branch=${BRANCH}" + + - name: Pre-flight checks + env: + GH_TOKEN: ${{ github.token }} + BRANCH: ${{ steps.ver.outputs.branch }} + TAG: ${{ steps.ver.outputs.tag }} + run: | + if git ls-remote --exit-code --heads origin "$BRANCH" >/dev/null 2>&1; then + echo "Error: branch '$BRANCH' already exists on origin" >&2 + exit 1 + fi + if git ls-remote --exit-code --tags origin "$TAG" >/dev/null 2>&1; then + echo "Error: tag '$TAG' already exists on origin" >&2 + exit 1 + fi + if gh release view "$TAG" >/dev/null 2>&1; then + echo "Error: release '$TAG' already exists" >&2 + exit 1 + fi + + - name: Configure git identity + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + - name: Create release branch + env: + BRANCH: ${{ steps.ver.outputs.branch }} + run: git switch -c "$BRANCH" + + - name: Bump versions + env: + VERSION: ${{ steps.ver.outputs.version }} + run: | + bun pm pkg set version="$VERSION" + (cd bin/cli && bun pm pkg set version="$VERSION") + (cd packages/jammin-sdk && bun pm pkg set version="$VERSION") + + - name: Commit and push + env: + TAG: ${{ steps.ver.outputs.tag }} + BRANCH: ${{ steps.ver.outputs.branch }} + run: | + git add package.json bin/cli/package.json packages/jammin-sdk/package.json + git commit -m "chore(release): bump version to ${TAG}" + git push origin "$BRANCH" + + - name: Create draft release + id: release + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ steps.ver.outputs.tag }} + run: | + RELEASE_URL=$(gh release create "$TAG" \ + --draft \ + --title "$TAG" \ + --notes "") + echo "url=${RELEASE_URL}" >> "$GITHUB_OUTPUT" + + - name: Open PR + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ steps.ver.outputs.tag }} + BRANCH: ${{ steps.ver.outputs.branch }} + RELEASE_URL: ${{ steps.release.outputs.url }} + run: | + cat > /tmp/pr_body.md < Date: Sat, 9 May 2026 00:10:59 +0200 Subject: [PATCH 2/2] Address CodeRabbit review on release-prepare workflow - Distinguish gh release view exit codes 0 (found), 1 (not found), and other (operational failure) so auth/network errors don't silently bypass the preflight. - Detect empty staged diff before commit to surface a clear error when the target version equals the current version. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/release-prepare.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release-prepare.yml b/.github/workflows/release-prepare.yml index 3019367..51296ed 100644 --- a/.github/workflows/release-prepare.yml +++ b/.github/workflows/release-prepare.yml @@ -68,9 +68,16 @@ jobs: echo "Error: tag '$TAG' already exists on origin" >&2 exit 1 fi - if gh release view "$TAG" >/dev/null 2>&1; then + set +e + gh release view "$TAG" >/dev/null 2>&1 + rc=$? + set -e + if [ "$rc" -eq 0 ]; then echo "Error: release '$TAG' already exists" >&2 exit 1 + elif [ "$rc" -ne 1 ]; then + echo "Error: failed to check release '$TAG' (gh exit code: $rc)" >&2 + exit 1 fi - name: Configure git identity @@ -97,6 +104,10 @@ jobs: BRANCH: ${{ steps.ver.outputs.branch }} run: | git add package.json bin/cli/package.json packages/jammin-sdk/package.json + if git diff --cached --quiet; then + echo "Error: no version changes to commit; package versions may already be ${TAG}" >&2 + exit 1 + fi git commit -m "chore(release): bump version to ${TAG}" git push origin "$BRANCH"