-
Notifications
You must be signed in to change notification settings - Fork 2
feat: add Homebrew formula and Scoop manifest with automated release workflow #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "version": "@VERSION@", | ||
| "description": "CLI for PT-Depiler browser extension via Native Messaging", | ||
| "homepage": "https://github.com/@REPOSITORY@", | ||
| "license": "MIT", | ||
| "architecture": {"64bit": {"url": "@WINDOWS_X86_64_URL@", "hash": "@WINDOWS_X86_64_SHA@"}}, | ||
| "bin": ["ptd.exe", "ptd-host.exe"], | ||
| "env_set": {"PTD_NATIVE_HOST_PATH": "$dir\\ptd-host.exe"}, | ||
| "checkver": "github", | ||
| "autoupdate": {"architecture": {"64bit": {"url": "https://github.com/@REPOSITORY@/releases/download/v$version/ptd-cli-v$version-x86_64-pc-windows-msvc.zip"}}} | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| class PtdCli < Formula | ||
| desc "CLI for PT-Depiler browser extension via Native Messaging" | ||
| homepage "https://github.com/@REPOSITORY@" | ||
| version "@VERSION@" | ||
| license "MIT" | ||
|
|
||
| on_macos do | ||
| if Hardware::CPU.arm? | ||
| url "@MACOS_ARM64_URL@" | ||
| sha256 "@MACOS_ARM64_SHA@" | ||
| else | ||
| url "@MACOS_X86_64_URL@" | ||
| sha256 "@MACOS_X86_64_SHA@" | ||
| end | ||
| end | ||
|
|
||
| on_linux do | ||
| if Hardware::CPU.arm? | ||
| url "@LINUX_ARM64_URL@" | ||
| sha256 "@LINUX_ARM64_SHA@" | ||
| else | ||
| url "@LINUX_X86_64_URL@" | ||
| sha256 "@LINUX_X86_64_SHA@" | ||
| end | ||
| end | ||
|
|
||
| def install | ||
| libexec.install "ptd", "ptd-host" | ||
| (bin/"ptd").write_env_script libexec/"ptd", | ||
| PTD_NATIVE_HOST_PATH: opt_libexec/"ptd-host" | ||
| end | ||
|
|
||
| test do | ||
| assert_match "ptd", shell_output("#{bin}/ptd --help") | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| VERSION="${1:?version is required}" | ||
| TAG="${2:?tag is required}" | ||
| REPOSITORY="${3:?repository is required}" | ||
| DIST="${4:?dist directory is required}" | ||
| OUTPUT="${GITHUB_WORKSPACE:-$(pwd)}/generated" | ||
| BASE_URL="https://github.com/${REPOSITORY}/releases/download/${TAG}" | ||
|
|
||
| sha() { sha256sum "$DIST/$1" | awk '{print $1}'; } | ||
| render() { | ||
| sed \ | ||
| -e "s|@VERSION@|${VERSION}|g" \ | ||
| -e "s|@REPOSITORY@|${REPOSITORY}|g" \ | ||
| -e "s|@MACOS_ARM64_URL@|${BASE_URL}/ptd-cli-${TAG}-aarch64-apple-darwin.tar.gz|g" \ | ||
| -e "s|@MACOS_ARM64_SHA@|$(sha "ptd-cli-${TAG}-aarch64-apple-darwin.tar.gz")|g" \ | ||
| -e "s|@MACOS_X86_64_URL@|${BASE_URL}/ptd-cli-${TAG}-x86_64-apple-darwin.tar.gz|g" \ | ||
| -e "s|@MACOS_X86_64_SHA@|$(sha "ptd-cli-${TAG}-x86_64-apple-darwin.tar.gz")|g" \ | ||
| -e "s|@LINUX_ARM64_URL@|${BASE_URL}/ptd-cli-${TAG}-aarch64-unknown-linux-gnu.tar.gz|g" \ | ||
| -e "s|@LINUX_ARM64_SHA@|$(sha "ptd-cli-${TAG}-aarch64-unknown-linux-gnu.tar.gz")|g" \ | ||
| -e "s|@LINUX_X86_64_URL@|${BASE_URL}/ptd-cli-${TAG}-x86_64-unknown-linux-gnu.tar.gz|g" \ | ||
| -e "s|@LINUX_X86_64_SHA@|$(sha "ptd-cli-${TAG}-x86_64-unknown-linux-gnu.tar.gz")|g" \ | ||
| -e "s|@WINDOWS_X86_64_URL@|${BASE_URL}/ptd-cli-${TAG}-x86_64-pc-windows-msvc.zip|g" \ | ||
| -e "s|@WINDOWS_X86_64_SHA@|$(sha "ptd-cli-${TAG}-x86_64-pc-windows-msvc.zip")|g" \ | ||
| "$1" > "$2" | ||
| } | ||
|
|
||
| mkdir -p "$OUTPUT" | ||
| render .github/release/ptd-cli.rb.in "$OUTPUT/ptd-cli.rb" | ||
| render .github/release/ptd-cli.json.in "$OUTPUT/ptd-cli.json" | ||
| jq empty "$OUTPUT/ptd-cli.json" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,63 +3,189 @@ name: Release | |
| on: | ||
| release: | ||
| types: [created] | ||
| workflow_dispatch: | ||
| inputs: | ||
| version: | ||
| description: Version without the v prefix (for example, 0.1.4) | ||
| required: true | ||
| type: string | ||
|
|
||
| permissions: | ||
| contents: write | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: release-${{ github.event.release.tag_name || inputs.version }} | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| prepare: | ||
| runs-on: ubuntu-22.04 | ||
| outputs: | ||
| source_sha: ${{ steps.source.outputs.sha }} | ||
| version: ${{ steps.source.outputs.version }} | ||
| tag: ${{ steps.source.outputs.tag }} | ||
| publish: ${{ steps.source.outputs.publish }} | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
| persist-credentials: false | ||
| - name: Validate release inputs | ||
| id: source | ||
| shell: bash | ||
| env: | ||
| RELEASE_TAG: ${{ github.event.release.tag_name }} | ||
| INPUT_VERSION: ${{ inputs.version }} | ||
| run: | | ||
| if [[ -n "$RELEASE_TAG" ]]; then | ||
| [[ "$RELEASE_TAG" == v* ]] || { echo "Release tag must start with v" >&2; exit 1; } | ||
| TAG="$RELEASE_TAG" | ||
| VERSION="${TAG#v}" | ||
| SOURCE_SHA="$(git rev-parse "${RELEASE_TAG}^{commit}")" | ||
| PUBLISH=true | ||
| else | ||
| VERSION="$INPUT_VERSION" | ||
| TAG="v${VERSION}" | ||
| SOURCE_SHA="$(git rev-parse HEAD)" | ||
| PUBLISH=false | ||
| fi | ||
| [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z.-]+)?$ ]] || { echo "Invalid semantic version" >&2; exit 1; } | ||
| { | ||
| echo "sha=$SOURCE_SHA" | ||
| echo "version=$VERSION" | ||
| echo "tag=$TAG" | ||
| echo "publish=$PUBLISH" | ||
| } >> "$GITHUB_OUTPUT" | ||
|
|
||
| build: | ||
| needs: prepare | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| include: | ||
| - target: x86_64-unknown-linux-gnu | ||
| os: ubuntu-latest | ||
| - target: aarch64-unknown-linux-gnu | ||
| os: ubuntu-latest | ||
| - target: x86_64-apple-darwin | ||
| os: macos-latest | ||
| - target: aarch64-apple-darwin | ||
| os: macos-latest | ||
| - target: x86_64-pc-windows-msvc | ||
| os: windows-latest | ||
|
|
||
| - {target: x86_64-unknown-linux-gnu, os: ubuntu-22.04} | ||
| - {target: aarch64-unknown-linux-gnu, os: ubuntu-22.04} | ||
| - {target: x86_64-apple-darwin, os: macos-15} | ||
| - {target: aarch64-apple-darwin, os: macos-15} | ||
| - {target: x86_64-pc-windows-msvc, os: windows-2022} | ||
| runs-on: ${{ matrix.os }} | ||
|
|
||
| env: | ||
| VERSION: ${{ needs.prepare.outputs.version }} | ||
| TAG: ${{ needs.prepare.outputs.tag }} | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Install Rust toolchain | ||
| uses: dtolnay/rust-toolchain@stable | ||
| with: | ||
| ref: ${{ needs.prepare.outputs.source_sha }} | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Security:
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in 48e3783. Workflow-level permissions now default to |
||
| persist-credentials: false | ||
| - uses: dtolnay/rust-toolchain@stable | ||
| with: | ||
| targets: ${{ matrix.target }} | ||
|
|
||
| - name: Install cross-compilation tools (aarch64-linux) | ||
| - name: Install cross-compilation tools | ||
| if: matrix.target == 'aarch64-unknown-linux-gnu' | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y gcc-aarch64-linux-gnu | ||
| echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV | ||
|
|
||
| echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc" >> "$GITHUB_ENV" | ||
| - name: Set package version | ||
| shell: bash | ||
| run: | | ||
| sed -i.bak -E "s/^version = \".*\"/version = \"${VERSION}\"/" Cargo.toml | ||
| cargo update -p ptd-cli | ||
| - name: Test | ||
| if: matrix.target == 'x86_64-unknown-linux-gnu' | ||
| run: cargo test --locked | ||
| - name: Build | ||
| run: cargo build --release --target ${{ matrix.target }} | ||
|
|
||
| - name: Package (unix) | ||
| run: cargo build --locked --release --target "${{ matrix.target }}" | ||
| - name: Smoke test native executable | ||
| if: matrix.target == 'x86_64-unknown-linux-gnu' | ||
| run: target/${{ matrix.target }}/release/ptd --help | ||
| - name: Package Unix binaries | ||
| if: runner.os != 'Windows' | ||
| run: | | ||
| cd target/${{ matrix.target }}/release | ||
| tar czf ../../../ptd-cli-${{ github.ref_name }}-${{ matrix.target }}.tar.gz ptd ptd-host | ||
| cd ../../.. | ||
|
|
||
| - name: Package (windows) | ||
| run: tar -C "target/${{ matrix.target }}/release" -czf "ptd-cli-${TAG}-${{ matrix.target }}.tar.gz" ptd ptd-host | ||
| - name: Package Windows binaries | ||
| if: runner.os == 'Windows' | ||
| shell: pwsh | ||
| run: Compress-Archive -Path "target/${{ matrix.target }}/release/ptd.exe","target/${{ matrix.target }}/release/ptd-host.exe" -DestinationPath "ptd-cli-$env:TAG-${{ matrix.target }}.zip" | ||
| - uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: release-${{ matrix.target }} | ||
| path: ptd-cli-${{ env.TAG }}-${{ matrix.target }}.* | ||
| if-no-files-found: error | ||
|
|
||
| compatibility: | ||
| name: Ubuntu 22.04 and Homebrew smoke test | ||
| needs: [prepare, build] | ||
| runs-on: ubuntu-22.04 | ||
| env: | ||
| VERSION: ${{ needs.prepare.outputs.version }} | ||
| TAG: ${{ needs.prepare.outputs.tag }} | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| ref: ${{ needs.prepare.outputs.source_sha }} | ||
| persist-credentials: false | ||
| - uses: Homebrew/actions/setup-homebrew@a657b8b0cd35d0f65cce41fce9b24cf054b49869 | ||
| - uses: actions/download-artifact@v4 | ||
| with: | ||
| name: release-x86_64-unknown-linux-gnu | ||
| path: dist | ||
| - name: Test packaged executable and formula | ||
| shell: bash | ||
| run: | | ||
| Compress-Archive -Path "target/${{ matrix.target }}/release/ptd.exe","target/${{ matrix.target }}/release/ptd-host.exe" -DestinationPath "ptd-cli-${{ github.ref_name }}-${{ matrix.target }}.zip" | ||
| tar -xzf "dist/ptd-cli-${TAG}-x86_64-unknown-linux-gnu.tar.gz" -C dist | ||
| dist/ptd --help | ||
| SHA="$(sha256sum "dist/ptd-cli-${TAG}-x86_64-unknown-linux-gnu.tar.gz" | awk '{print $1}')" | ||
| sed -e "s/@VERSION@/${VERSION}/g" \ | ||
| -e "s|@REPOSITORY@|${GITHUB_REPOSITORY}|g" \ | ||
| -e "s|@LINUX_X86_64_URL@|file://${GITHUB_WORKSPACE}/dist/ptd-cli-${TAG}-x86_64-unknown-linux-gnu.tar.gz|g" \ | ||
| -e "s/@LINUX_X86_64_SHA@/${SHA}/g" \ | ||
| .github/release/ptd-cli.rb.in > /tmp/ptd-cli.rb | ||
| git config --global user.name "github-actions[bot]" | ||
| git config --global user.email "github-actions[bot]@users.noreply.github.com" | ||
| brew tap-new ptd-test/release | ||
| cp /tmp/ptd-cli.rb "$(brew --repository ptd-test/release)/Formula/ptd-cli.rb" | ||
| brew install --formula ptd-test/release/ptd-cli | ||
| brew test ptd-test/release/ptd-cli | ||
|
|
||
| - name: Upload release assets | ||
| uses: softprops/action-gh-release@v2 | ||
| publish: | ||
| name: Publish assets, then manifests | ||
| needs: [prepare, build, compatibility] | ||
| if: needs.prepare.outputs.publish == 'true' | ||
| runs-on: ubuntu-22.04 | ||
| permissions: | ||
| contents: write | ||
| env: | ||
| VERSION: ${{ needs.prepare.outputs.version }} | ||
| TAG: ${{ needs.prepare.outputs.tag }} | ||
| GH_TOKEN: ${{ github.token }} | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| files: | | ||
| ptd-cli-${{ github.ref_name }}-${{ matrix.target }}.tar.gz | ||
| ptd-cli-${{ github.ref_name }}-${{ matrix.target }}.zip | ||
| ref: ${{ github.event.repository.default_branch }} | ||
| fetch-depth: 0 | ||
| - uses: actions/download-artifact@v4 | ||
| with: | ||
| pattern: release-* | ||
| path: dist | ||
| merge-multiple: true | ||
| - name: Upload and verify every release asset | ||
| shell: bash | ||
| run: | | ||
| gh release upload "$TAG" dist/* --clobber | ||
| ASSETS="$(gh release view "$TAG" --json assets --jq '.assets[].name')" | ||
| for asset in dist/*; do grep -Fxq "$(basename "$asset")" <<< "$ASSETS"; done | ||
| - name: Generate release manifests | ||
| run: .github/release/render-manifests.sh "$VERSION" "$TAG" "$GITHUB_REPOSITORY" dist | ||
| - name: Publish release metadata idempotently | ||
| shell: bash | ||
| run: | | ||
| git pull --ff-only origin "${{ github.event.repository.default_branch }}" | ||
| mkdir -p Formula bucket | ||
| cp generated/ptd-cli.rb Formula/ptd-cli.rb | ||
| cp generated/ptd-cli.json bucket/ptd-cli.json | ||
| git add Formula/ptd-cli.rb bucket/ptd-cli.json | ||
| if git diff --cached --quiet; then echo "Release metadata is already current"; exit 0; fi | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "github-actions[bot]@users.noreply.github.com" | ||
| git commit -m "chore(release): publish ${TAG} [skip ci]" | ||
| git push origin HEAD:${{ github.event.repository.default_branch }} | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This sequence is not atomic or safely retryable. Once this push succeeds, a later tag or release failure leaves public manifests pointing to assets that do not exist. If the tag push succeeds but
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in 48e3783. The workflow no longer creates or rejects an existing tag: it starts from the existing GitHub Release, uploads every asset with |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This removes the existing
release.createdentry point and adds neither a release nor tag trigger, so creating a GitHub release through the previous workflow no longer builds or uploads anything. It also conflicts with the PR description's claim that updates happen on release/tag pushes. Please retain a compatible trigger, or obtain explicit maintainer consent for the breaking release-process migration and update the PR/release documentation accordingly. Verify the selected release event actually starts the workflow.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 48e3783. The compatible
release.createdtrigger is restored, while manual dispatch remains build/test-only. I verified the event independently in the standalone release-test repository with a minimal workflow on its temporary default branch; the log recordsaction=createdand completed successfully: https://github.com/NanamiMio/ptd-cli-release-test/actions/runs/32801398025