Skip to content

fix: resolve --force-transfer-mode being a no-op for missing transfer… #81

fix: resolve --force-transfer-mode being a no-op for missing transfer…

fix: resolve --force-transfer-mode being a no-op for missing transfer… #81

Workflow file for this run

name: Release
on:
push:
branches:
- main
workflow_dispatch:
concurrency:
group: release
cancel-in-progress: false
permissions:
contents: write
pull-requests: write
packages: write
jobs:
# Step 1: Detect changesets and either create a version PR or flag for release
changesets:
runs-on: ubuntu-latest
outputs:
should_release: ${{ steps.detect.outputs.should_release }}
has_cli_release: ${{ steps.detect.outputs.has_cli_release }}
has_docker_release: ${{ steps.detect.outputs.has_docker_release }}
cli_version: ${{ steps.detect.outputs.cli_version }}
docker_version: ${{ steps.detect.outputs.docker_version }}
hasChangesets: ${{ steps.changesets.outputs.hasChangesets }}
steps:
- name: Generate app token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- uses: actions/checkout@v4
with:
token: ${{ steps.app-token.outputs.token }}
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install --frozen-lockfile --ignore-scripts
- name: Create release Pull Request or detect release merge
id: changesets
uses: changesets/action@v1
with:
version: bun run version
publish: echo "publish-placeholder"
title: 'Version Packages'
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
- name: Detect if this is a release merge
id: detect
run: |
CLI_VERSION=$(jq -r '.version' packages/podkit-cli/package.json)
CLI_TAG="podkit@$CLI_VERSION"
DOCKER_VERSION=$(jq -r '.version' packages/podkit-docker/package.json)
DOCKER_TAG="docker@$DOCKER_VERSION"
echo "cli_version=$CLI_VERSION" >> "$GITHUB_OUTPUT"
echo "docker_version=$DOCKER_VERSION" >> "$GITHUB_OUTPUT"
if [ "${{ steps.changesets.outputs.hasChangesets }}" = "false" ]; then
# No pending changesets — check if this is a release-worthy commit
COMMIT_MSG=$(git log -1 --format="%s")
echo "Commit message: $COMMIT_MSG"
IS_RELEASE=false
# Release if: Version Packages merge OR manual dispatch with unreleased version
if echo "$COMMIT_MSG" | grep -q "Version Packages"; then
IS_RELEASE=true
echo "Release detected — Version Packages merge"
elif [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
IS_RELEASE=true
echo "Manual dispatch — checking for unreleased versions"
fi
if [ "$IS_RELEASE" = "true" ]; then
git fetch --tags
if git rev-parse "$CLI_TAG" >/dev/null 2>&1; then
echo "has_cli_release=false" >> "$GITHUB_OUTPUT"
echo "CLI version $CLI_VERSION already released"
else
echo "has_cli_release=true" >> "$GITHUB_OUTPUT"
echo "CLI version $CLI_VERSION is new — will release"
fi
if git rev-parse "$DOCKER_TAG" >/dev/null 2>&1; then
echo "has_docker_release=false" >> "$GITHUB_OUTPUT"
echo "Docker version $DOCKER_VERSION already released"
else
echo "has_docker_release=true" >> "$GITHUB_OUTPUT"
echo "Docker version $DOCKER_VERSION is new — will release"
fi
else
echo "has_cli_release=false" >> "$GITHUB_OUTPUT"
echo "has_docker_release=false" >> "$GITHUB_OUTPUT"
echo "No changesets and not a version merge — nothing to do"
fi
else
echo "has_cli_release=false" >> "$GITHUB_OUTPUT"
echo "has_docker_release=false" >> "$GITHUB_OUTPUT"
echo "Pending changesets found — version PR will be created/updated"
fi
# Set should_release based on whether either component needs releasing.
# Re-read the outputs file since they were just written above.
if grep -q "has_cli_release=true" "$GITHUB_OUTPUT" || grep -q "has_docker_release=true" "$GITHUB_OUTPUT"; then
echo "should_release=true" >> "$GITHUB_OUTPUT"
else
echo "should_release=false" >> "$GITHUB_OUTPUT"
fi
# Step 2: Build native prebuilds + compile CLI binaries for each platform
# Prebuild cache is shared with verify-release.yml — on typical version
# merges (no native code changes), prebuilds hit cache and only TypeScript
# build + Bun compile runs.
build:
needs: changesets
if: needs.changesets.outputs.should_release == 'true'
uses: ./.github/workflows/build-platform.yml
with:
upload-artifacts: true
# Step 3: Create GitHub Release with all platform tarballs (CLI releases only)
release:
needs: [changesets, build]
if: needs.build.result == 'success' && needs.changesets.outputs.has_cli_release == 'true'
runs-on: ubuntu-latest
name: Create GitHub Release
outputs:
version: ${{ needs.changesets.outputs.cli_version }}
tag: ${{ steps.tag.outputs.tag }}
steps:
- uses: actions/checkout@v4
- name: Set tag
id: tag
run: |
echo "tag=podkit@${{ needs.changesets.outputs.cli_version }}" >> "$GITHUB_OUTPUT"
- name: Download all tarballs
uses: actions/download-artifact@v4
with:
pattern: podkit-*
path: release-assets/
merge-multiple: true
- name: List release assets
run: ls -la release-assets/
- name: Generate SHA256 checksums
working-directory: release-assets
run: |
sha256sum podkit-*.tar.gz > SHA256SUMS.txt
cat SHA256SUMS.txt
- name: Build release notes
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
NOTES_FILE="release-notes.md"
VERSION="${{ needs.changesets.outputs.cli_version }}"
: > "$NOTES_FILE"
# Add version PR description at the top if available
PR_BODY=$(gh pr list --state merged --search "\"Version Packages\" in:title" --limit 1 --json body --jq '.[0].body // empty')
if [ -n "$PR_BODY" ]; then
echo "$PR_BODY" >> "$NOTES_FILE"
echo "" >> "$NOTES_FILE"
echo "---" >> "$NOTES_FILE"
echo "" >> "$NOTES_FILE"
fi
# Add changelog from CHANGELOG.md
echo "## Changelog" >> "$NOTES_FILE"
echo "" >> "$NOTES_FILE"
CHANGELOG_FILE="packages/podkit-cli/CHANGELOG.md"
if [ -f "$CHANGELOG_FILE" ]; then
# Extract the latest version section (from first ## to the next ##)
awk '/^## [0-9]/{if(found) exit; found=1; next} found{print}' "$CHANGELOG_FILE" >> "$NOTES_FILE"
else
echo "Release $VERSION" >> "$NOTES_FILE"
fi
echo "" >> "$NOTES_FILE"
# Add checksums
echo "## Checksums (SHA256)" >> "$NOTES_FILE"
echo "" >> "$NOTES_FILE"
echo '```' >> "$NOTES_FILE"
cat release-assets/SHA256SUMS.txt >> "$NOTES_FILE"
echo '```' >> "$NOTES_FILE"
echo "--- Release notes ---"
cat "$NOTES_FILE"
- name: Create tag and GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG="${{ steps.tag.outputs.tag }}"
VERSION="${{ needs.changesets.outputs.cli_version }}"
if git rev-parse "$TAG" >/dev/null 2>&1; then
echo "Tag $TAG already exists — skipping release"
exit 0
fi
git tag "$TAG"
git push origin "$TAG"
gh release create "$TAG" \
--title "podkit $VERSION" \
--notes-file release-notes.md \
release-assets/podkit-*.tar.gz \
release-assets/SHA256SUMS.txt
# Step 4: Build and push Docker image to GHCR (Docker releases only)
docker:
needs: [changesets, build]
if: needs.build.result == 'success' && needs.changesets.outputs.has_docker_release == 'true'
uses: ./.github/workflows/docker.yml
with:
version: ${{ needs.changesets.outputs.docker_version }}
push: true
permissions:
contents: read
packages: write
# Step 4b: Tag Docker release after successful push
docker-tag:
needs: [changesets, docker]
if: needs.docker.result == 'success'
runs-on: ubuntu-latest
name: Tag Docker Release
steps:
- uses: actions/checkout@v4
- name: Create Docker release tag
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG="docker@${{ needs.changesets.outputs.docker_version }}"
if git rev-parse "$TAG" >/dev/null 2>&1; then
echo "Tag $TAG already exists"
else
git tag "$TAG"
git push origin "$TAG"
echo "Created tag $TAG"
fi
# Step 5: Update the Homebrew formula in the tap repository (CLI releases only)
update-homebrew:
needs: [changesets, release]
if: needs.release.result == 'success'
runs-on: ubuntu-latest
continue-on-error: true
name: Update Homebrew Formula
steps:
- uses: actions/checkout@v4
- name: Download checksums from release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG="${{ needs.release.outputs.tag }}"
mkdir -p checksums
gh release download "$TAG" --pattern "SHA256SUMS.txt" --dir checksums
- name: Checkout homebrew-podkit
uses: actions/checkout@v4
with:
repository: jvgomg/homebrew-podkit
path: homebrew-tap
ssh-key: ${{ secrets.HOMEBREW_TAP_DEPLOY_KEY }}
- name: Update formula
run: |
VERSION="${{ needs.release.outputs.version }}"
./tools/update-homebrew-formula.sh "$VERSION" homebrew-tap/Formula/podkit.rb checksums/SHA256SUMS.txt
- name: Commit and push
working-directory: homebrew-tap
run: |
VERSION="${{ needs.release.outputs.version }}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Formula/podkit.rb
git diff --cached --quiet && echo "No changes to commit" && exit 0
git commit -m "Update podkit to $VERSION"
git push