Skip to content

Add release infrastructure and distribution docs #1

Add release infrastructure and distribution docs

Add release infrastructure and distribution docs #1

Workflow file for this run

name: Release
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
tag:
description: "Tag to release (e.g. v0.1.0). Must already exist."
required: true
permissions:
contents: write
jobs:
build:
name: Build ${{ matrix.target }}
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- target: macos-arm64
runner: macos-14
archive: tar.gz
- target: macos-x86_64
runner: macos-13
archive: tar.gz
- target: linux-arm64
runner: ubuntu-24.04-arm
archive: tar.gz
- target: linux-x86_64
runner: ubuntu-24.04
archive: tar.gz
- target: windows-x86_64
runner: windows-latest
archive: zip
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.tag || github.ref }}
- name: Setup Dart
uses: dart-lang/setup-dart@v1
- name: Resolve tag
id: tag
shell: bash
run: |
if [ -n "${{ github.event.inputs.tag }}" ]; then
echo "name=${{ github.event.inputs.tag }}" >> "$GITHUB_OUTPUT"
else
echo "name=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
fi
- name: Verify pubspec version matches tag
shell: bash
run: |
tag="${{ steps.tag.outputs.name }}"
pubspec_version=$(awk '/^version:/ {print $2}' pubspec.yaml)
expected="v${pubspec_version}"
if [ "$tag" != "$expected" ]; then
echo "::error::Tag $tag does not match pubspec.yaml version $pubspec_version (expected $expected)"
exit 1
fi
- name: Install dependencies
run: dart pub get
- name: Compile binary (Unix)
if: runner.os != 'Windows'
run: |
mkdir -p build
dart compile exe bin/space.dart -o build/space
- name: Compile binary (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path build | Out-Null
dart compile exe bin/space.dart -o build/space.exe
- name: Package archive (Unix)
if: matrix.archive == 'tar.gz'
shell: bash
run: |
name="space-cli-${{ matrix.target }}"
staging="dist/$name"
mkdir -p "$staging"
cp build/space "$staging/"
cp README.md LICENSE "$staging/" 2>/dev/null || cp README.md "$staging/"
tar -czf "dist/${name}.tar.gz" -C dist "$name"
(cd dist && shasum -a 256 "${name}.tar.gz" > "${name}.tar.gz.sha256")
- name: Package archive (Windows)
if: matrix.archive == 'zip'
shell: pwsh
run: |
$name = "space-cli-${{ matrix.target }}"
$staging = "dist/$name"
New-Item -ItemType Directory -Force -Path $staging | Out-Null
Copy-Item build/space.exe "$staging/"
Copy-Item README.md "$staging/"
Compress-Archive -Path "$staging/*" -DestinationPath "dist/${name}.zip"
$hash = (Get-FileHash -Algorithm SHA256 "dist/${name}.zip").Hash.ToLower()
"$hash ${name}.zip" | Out-File -FilePath "dist/${name}.zip.sha256" -Encoding ascii
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.target }}
path: |
dist/*.tar.gz
dist/*.zip
dist/*.sha256
if-no-files-found: error
retention-days: 7
release:
name: Publish GitHub Release
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Assemble checksums.txt
run: |
mkdir -p release
find artifacts -type f \( -name "*.tar.gz" -o -name "*.zip" \) -exec cp {} release/ \;
cd release
sha256sum ./*.tar.gz ./*.zip | sed 's| \./| |g' > checksums.txt
cat checksums.txt
- name: Resolve tag
id: tag
run: |
if [ -n "${{ github.event.inputs.tag }}" ]; then
echo "name=${{ github.event.inputs.tag }}" >> "$GITHUB_OUTPUT"
else
echo "name=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
fi
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.tag.outputs.name }}
name: ${{ steps.tag.outputs.name }}
draft: false
prerelease: ${{ contains(steps.tag.outputs.name, '-') }}
generate_release_notes: true
files: |
release/*.tar.gz
release/*.zip
release/checksums.txt
homebrew:
name: Update Homebrew Tap
runs-on: ubuntu-latest
needs: release
if: ${{ !contains(github.ref, '-') }}
steps:
- name: Checkout tap
uses: actions/checkout@v4
with:
repository: space-org/homebrew-tap
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
path: tap
- name: Resolve tag and version
id: meta
run: |
tag="${GITHUB_REF#refs/tags/}"
echo "tag=$tag" >> "$GITHUB_OUTPUT"
echo "version=${tag#v}" >> "$GITHUB_OUTPUT"
- name: Fetch checksums
id: sums
run: |
tag="${{ steps.meta.outputs.tag }}"
base="https://github.com/${{ github.repository }}/releases/download/${tag}"
curl -fsSL "${base}/checksums.txt" -o checksums.txt
get() { grep " $1$" checksums.txt | awk '{print $1}'; }
{
echo "macos_arm64=$(get space-cli-macos-arm64.tar.gz)"
echo "macos_x86_64=$(get space-cli-macos-x86_64.tar.gz)"
echo "linux_arm64=$(get space-cli-linux-arm64.tar.gz)"
echo "linux_x86_64=$(get space-cli-linux-x86_64.tar.gz)"
} >> "$GITHUB_OUTPUT"
- name: Render formula
run: |
cat > tap/Formula/space-cli.rb <<EOF
class SpaceCli < Formula
desc "CLI for querying your local Space flashcard database"
homepage "https://getspace.dev/cli"
version "${{ steps.meta.outputs.version }}"
license "MIT"
on_macos do
on_arm do
url "https://github.com/${{ github.repository }}/releases/download/${{ steps.meta.outputs.tag }}/space-cli-macos-arm64.tar.gz"
sha256 "${{ steps.sums.outputs.macos_arm64 }}"
end
on_intel do
url "https://github.com/${{ github.repository }}/releases/download/${{ steps.meta.outputs.tag }}/space-cli-macos-x86_64.tar.gz"
sha256 "${{ steps.sums.outputs.macos_x86_64 }}"
end
end
on_linux do
on_arm do
url "https://github.com/${{ github.repository }}/releases/download/${{ steps.meta.outputs.tag }}/space-cli-linux-arm64.tar.gz"
sha256 "${{ steps.sums.outputs.linux_arm64 }}"
end
on_intel do
url "https://github.com/${{ github.repository }}/releases/download/${{ steps.meta.outputs.tag }}/space-cli-linux-x86_64.tar.gz"
sha256 "${{ steps.sums.outputs.linux_x86_64 }}"
end
end
def install
bin.install "space"
end
test do
assert_match "space-cli", shell_output("#{bin}/space --version")
end
end
EOF
- name: Commit and push
run: |
cd tap
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add Formula/space-cli.rb
if git diff --cached --quiet; then
echo "No changes to formula."
exit 0
fi
git commit -m "space-cli ${{ steps.meta.outputs.tag }}"
git push