name: Publish
on:
workflow_dispatch:
inputs:
tag:
description: 'Tag to publish (e.g., v1.2.3)'
required: true
type: string
permissions:
contents: write
packages: write
id-token: write
jobs:
prepare:
name: Prepare Release
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
tag: ${{ steps.version.outputs.tag }}
steps:
- name: Extract version from tag
id: version
run: |
TAG="${{ inputs.tag }}"
VERSION="${TAG#v}"
echo "tag=$TAG" >> $GITHUB_OUTPUT
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Releasing version: $VERSION (tag: $TAG)"
publish-crates:
name: Publish to crates.io
needs: prepare
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ needs.prepare.outputs.tag }}
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Publish to crates.io
run: cargo publish
build-binaries:
name: Build Binaries
needs: prepare
uses: ./.github/workflows/_build-binaries.yml
with:
ref: ${{ needs.prepare.outputs.tag }}
upload-artifacts: true
artifact-retention-days: 1
build-packages:
name: Build Packages
needs: prepare
uses: ./.github/workflows/_build-packages.yml
with:
ref: ${{ needs.prepare.outputs.tag }}
version: ${{ needs.prepare.outputs.version }}
artifact-retention-days: 1
create-github-release:
name: Create GitHub Release
needs: [prepare, build-binaries, build-packages]
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ needs.prepare.outputs.tag }}
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Display structure
run: ls -R artifacts
- name: Extract release notes from CHANGELOG
id: release_notes
run: |
VERSION="${{ needs.prepare.outputs.version }}"
# Extract the section for this version from CHANGELOG.md
# The changelog format is: ## [version](url) (date)
# We want everything between this version header and the next ## header
# Use awk to extract the section
NOTES=$(awk -v ver="$VERSION" '
/^## \[/ {
if (found) exit
if (index($0, "[" ver "]")) found=1
next
}
found { print }
' CHANGELOG.md)
# If no notes found, use a default message
if [ -z "$NOTES" ]; then
NOTES="Release v$VERSION"
fi
# Write to file to handle multiline content
echo "$NOTES" > release_notes.md
echo "Release notes extracted for v$VERSION"
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.prepare.outputs.tag }}
name: ${{ needs.prepare.outputs.tag }}
body_path: release_notes.md
files: artifacts/**/*
fail_on_unmatched_files: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
docker:
name: Build and Push Docker Image
needs: [prepare, build-binaries]
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ needs.prepare.outputs.tag }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=semver,pattern={{version}},value=${{ needs.prepare.outputs.version }}
type=semver,pattern={{major}}.{{minor}},value=${{ needs.prepare.outputs.version }}
type=semver,pattern={{major}},value=${{ needs.prepare.outputs.version }}
type=raw,value=latest
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
update-package-repos:
name: Trigger ${{ matrix.name }} Update
needs: [prepare, create-github-release]
runs-on: ubuntu-latest
strategy:
matrix:
include:
- name: Homebrew
repo: bordeux/homebrew-tap
token_env: HOMEBREW_TAP_TOKEN
- name: APT Repository
repo: bordeux/apt-repo
token_env: APT_REPO_TOKEN
- name: APK Repository
repo: bordeux/apk-repo
token_env: APK_REPO_TOKEN
- name: RPM Repository
repo: bordeux/rpm-repo
token_env: RPM_REPO_TOKEN
- name: ARCH Repository
repo: bordeux/arch-repo
token_env: ARCH_REPO_TOKEN
steps:
- name: Trigger ${{ matrix.name }} workflow
env:
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
APT_REPO_TOKEN: ${{ secrets.APT_REPO_TOKEN }}
APK_REPO_TOKEN: ${{ secrets.APK_REPO_TOKEN }}
RPM_REPO_TOKEN: ${{ secrets.RPM_REPO_TOKEN }}
ARCH_REPO_TOKEN: ${{ secrets.ARCH_REPO_TOKEN }}
run: |
TOKEN_VAR="${{ matrix.token_env }}"
TOKEN="${!TOKEN_VAR}"
curl -X POST \
-H "Authorization: token $TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${{ matrix.repo }}/actions/workflows/update-repo.yml/dispatches" \
-d '{"ref":"master","inputs":{"project":"bordeux/tmpltool"}}'