Skip to content

Release sce CLI

Release sce CLI #26

Workflow file for this run

name: Release sce CLI
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
target:
description: "Branch or commit SHA to tag"
required: false
default: main
prerelease:
description: "Mark the GitHub Release as a pre-release"
required: false
type: boolean
default: false
permissions:
contents: write
jobs:
create-tag:
if: github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.release_meta.outputs.tag }}
version: ${{ steps.release_meta.outputs.version }}
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
- name: Check out repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ inputs.target }}
fetch-depth: 0
- 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: Resolve checked-in release version
id: release_meta
shell: bash
run: |
set -euo pipefail
cargo_version="$(sed -n 's/^version = "\([^"]*\)"$/\1/p' cli/Cargo.toml | head -n 1)"
npm_version="$(node -p "JSON.parse(require('fs').readFileSync('npm/package.json', 'utf8')).version")"
version="$(tr -d '\n' < .version)"
tag="v${version}"
if [ "$cargo_version" != "$version" ]; then
printf 'cli/Cargo.toml version %s does not match .version %s\n' "$cargo_version" "$version" >&2
exit 1
fi
if [ "$npm_version" != "$version" ]; then
printf 'npm/package.json version %s does not match .version %s\n' "$npm_version" "$version" >&2
exit 1
fi
if git rev-parse "$tag" >/dev/null 2>&1; then
printf 'Release tag %s already exists. Update .version or use the existing tag.\n' "$tag" >&2
exit 1
fi
echo "tag=$tag" >> "$GITHUB_OUTPUT"
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "Selected checked-in release version: $tag"
- name: Create and push tag
run: |
git tag "${{ steps.release_meta.outputs.tag }}" "${{ inputs.target }}"
git push origin "${{ steps.release_meta.outputs.tag }}"
resolve-release:
needs: create-tag
if: always() && (github.event_name == 'push' || needs.create-tag.result == 'success')
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.resolve.outputs.tag }}
version: ${{ steps.resolve.outputs.version }}
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
- name: Resolve checkout ref
id: checkout_ref
if: github.event_name == 'workflow_dispatch'
shell: bash
run: |
set -euo pipefail
ref="${{ needs.create-tag.outputs.tag || inputs.target }}"
if [ -z "$ref" ]; then
echo "No release ref available from create-tag output or inputs.target" >&2
exit 1
fi
remote_url="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY.git"
if ! git ls-remote --exit-code --heads "$remote_url" "$ref" >/dev/null 2>&1 \
&& ! git ls-remote --exit-code --tags "$remote_url" "$ref" >/dev/null 2>&1; then
if [[ "$ref" =~ ^[0-9]+\.[0-9]+\.[0-9]+([.-].*)?$ ]]; then
candidate="v$ref"
if git ls-remote --exit-code --tags "$remote_url" "$candidate" >/dev/null 2>&1; then
ref="$candidate"
fi
fi
fi
if ! git ls-remote --exit-code --heads "$remote_url" "$ref" >/dev/null 2>&1 \
&& ! git ls-remote --exit-code --tags "$remote_url" "$ref" >/dev/null 2>&1; then
printf 'Release ref %s does not exist as a branch or tag\n' "$ref" >&2
exit 1
fi
echo "ref=$ref" >> "$GITHUB_OUTPUT"
- name: Check out repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ github.event_name == 'workflow_dispatch' && steps.checkout_ref.outputs.ref || github.ref_name }}
fetch-depth: 0
- name: Resolve release version
id: resolve
shell: bash
env:
DISPATCH_TAG: ${{ needs.create-tag.outputs.tag }}
DISPATCH_REF: ${{ steps.checkout_ref.outputs.ref }}
EVENT_NAME: ${{ github.event_name }}
PUSH_TAG: ${{ github.ref_name }}
run: |
set -euo pipefail
cargo_version="$(sed -n 's/^version = "\([^"]*\)"$/\1/p' cli/Cargo.toml | head -n 1)"
npm_version="$(node -p "JSON.parse(require('fs').readFileSync('npm/package.json', 'utf8')).version")"
if [ -n "$DISPATCH_TAG" ]; then
tag="$DISPATCH_TAG"
elif [ "$EVENT_NAME" = "workflow_dispatch" ]; then
tag="$DISPATCH_REF"
else
tag="$PUSH_TAG"
fi
version="${tag#v}"
checked_in_version="$(tr -d '\n' < .version)"
if [ "$checked_in_version" != "$version" ]; then
printf 'Release tag %s does not match checked-in .version %s\n' "$tag" "$checked_in_version" >&2
exit 1
fi
if [ "$cargo_version" != "$version" ]; then
printf 'cli/Cargo.toml version %s does not match .version %s\n' "$cargo_version" "$version" >&2
exit 1
fi
if [ "$npm_version" != "$version" ]; then
printf 'npm/package.json version %s does not match .version %s\n' "$npm_version" "$version" >&2
exit 1
fi
echo "tag=$tag" >> "$GITHUB_OUTPUT"
echo "version=$version" >> "$GITHUB_OUTPUT"
build-linux:
needs: resolve-release
if: needs.resolve-release.result == 'success'
uses: ./.github/workflows/release-sce-linux.yml
with:
release_ref: ${{ needs.resolve-release.outputs.tag }}
release_version: ${{ needs.resolve-release.outputs.version }}
build-linux-arm:
needs: resolve-release
if: needs.resolve-release.result == 'success'
uses: ./.github/workflows/release-sce-linux-arm.yml
with:
release_ref: ${{ needs.resolve-release.outputs.tag }}
release_version: ${{ needs.resolve-release.outputs.version }}
build-macos-arm:
needs: resolve-release
if: needs.resolve-release.result == 'success'
uses: ./.github/workflows/release-sce-macos-arm.yml
with:
release_ref: ${{ needs.resolve-release.outputs.tag }}
release_version: ${{ needs.resolve-release.outputs.version }}
release:
needs:
- resolve-release
- build-linux
- build-linux-arm
- build-macos-arm
if: |
needs.resolve-release.result == 'success' &&
needs.build-linux.result == 'success' &&
needs.build-linux-arm.result == 'success' &&
needs.build-macos-arm.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
- name: Check out repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ needs.resolve-release.outputs.tag }}
- name: Install Nix
uses: DeterminateSystems/determinate-nix-action@629b284231c2a82554b724e357e47fc6020833c8 # v3.21.2
- name: Download CLI release artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: sce-release-*
path: dist/cli
merge-multiple: true
- name: Assemble CLI release manifest
env:
SCE_RELEASE_MANIFEST_SIGNING_KEY: ${{ secrets.SCE_RELEASE_MANIFEST_SIGNING_KEY }}
run: |
nix run .#release-manifest -- \
--version "${{ needs.resolve-release.outputs.version }}" \
--artifacts-dir dist/cli \
--out-dir dist/cli
- name: Build npm release package
run: |
nix run .#release-npm-package -- \
--version "${{ needs.resolve-release.outputs.version }}" \
--out-dir dist/npm
- name: Build Flatpak source-manifest release package
run: |
nix run .#release-flatpak-package -- \
--version "${{ needs.resolve-release.outputs.version }}" \
--out-dir dist/flatpak
- name: Download Flatpak bundle release assets
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: sce-flatpak-bundle-*
path: dist/flatpak-bundle
merge-multiple: true
- name: Create GitHub release
uses: softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3.0.1
with:
tag_name: ${{ needs.resolve-release.outputs.tag }}
name: sce ${{ needs.resolve-release.outputs.tag }}
prerelease: ${{ github.event_name == 'workflow_dispatch' && inputs.prerelease || false }}
generate_release_notes: true
body: |
## CLI release assets
- Canonical `sce` archives are published as `sce-v<version>-<target-triple>.tar.gz`
- Per-archive SHA-256 checksum files are published as `sce-v<version>-<target-triple>.tar.gz.sha256`
- Combined artifact metadata is published as `sce-v<version>-release-manifest.json`
- Combined artifact manifest signatures are published as `sce-v<version>-release-manifest.json.sig`
- Combined checksums are published as `sce-v<version>-SHA256SUMS`
- The npm package tarball is published as `sce-v<version>-npm.tgz`
- Flatpak source-built packaging metadata is published as `sce-v<version>-flatpak-manifest.tar.gz`, with matching `.sha256` and `.json` metadata assets; this is not a prebuilt Flatpak app or Flathub publication.
- Flatpak source-built `.flatpak` bundles are published as `sce-v<version>-x86_64.flatpak` and `sce-v<version>-aarch64.flatpak`, with matching `.sha256` and `.json` metadata assets; install directly with `flatpak install --user <url>`.
files: |
dist/cli/*.tar.gz
dist/cli/*.sha256
dist/cli/*release-manifest.json
dist/cli/*release-manifest.json.sig
dist/cli/*SHA256SUMS
dist/npm/*.tgz
dist/npm/*.json
dist/flatpak/*.tar.gz
dist/flatpak/*.sha256
dist/flatpak/*.json
dist/flatpak-bundle/*.flatpak
dist/flatpak-bundle/*.sha256
dist/flatpak-bundle/*.json