Skip to content

prebuild: add eudev-dev to Alpine musl apk install #93

prebuild: add eudev-dev to Alpine musl apk install

prebuild: add eudev-dev to Alpine musl apk install #93

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: Sync docs-live branch to the release commit so the docs site deploys.
# docs-live is a deployment branch — only updated by this job (on release) or
# by manual cherry-pick (for docs-only tweaks). Pushing to docs-live triggers
# deploy-docs.yml.
#
# Force-with-lease is safe here: any commits on docs-live (from docs-only
# cherry-picks) must already exist on main, since cherry-picks always
# originate from main. Resetting docs-live to the release commit realigns
# the branch without losing content.
sync-docs-live:
needs: [changesets, release, docker-tag]
# Run only if every component that was supposed to release did release.
# always() is required because some needs may be skipped (CLI-only or
# Docker-only releases). For each component: if it wasn't being released,
# we don't care about its result; if it was, it must have succeeded.
if: |
always() &&
needs.changesets.outputs.should_release == 'true' &&
(needs.changesets.outputs.has_cli_release != 'true' || needs.release.result == 'success') &&
(needs.changesets.outputs.has_docker_release != 'true' || needs.docker-tag.result == 'success')
runs-on: ubuntu-latest
name: Sync docs-live to release
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Reset docs-live to release commit
run: |
git fetch origin docs-live
git push origin HEAD:docs-live --force-with-lease
# Step 6: 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