name: release
on:
workflow_dispatch:
inputs:
upload_artifacts:
description: "Upload build artifacts"
required: false
default: "true"
type: choice
options: ["true", "false"]
release_tag:
description: "Tag to publish the release under (required when run manually, e.g. v0.1.3)"
required: false
default: ""
type: string
push:
tags: ["v*"]
env:
CARGO_TERM_COLOR: always
BINARY_NAME: liepress
jobs:
build-x86_64-linux:
name: Build x86_64 Linux (gnu)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Compute version
id: version
shell: bash
run: |
# 版本号提取(支持语义化版本,含预发布/构建后缀,如 v0.1.4-beta.1)
if [[ "${{ github.event_name }}" == "push" ]]; then
TAG="${{ github.ref_name }}"
else
TAG="${{ github.event.inputs.release_tag }}"
fi
VER="${TAG#v}"
# 完整 SemVer 匹配:MAJOR.MINOR.PATCH[-pre][+build],未匹配则回退 Cargo.toml
if [[ ! "$VER" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$ ]]; then
VER="$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"([0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?)".*/\1/')"
fi
echo "version=v${VER}" >> "$GITHUB_OUTPUT"
- uses: dtolnay/rust-toolchain@stable
with:
targets: x86_64-unknown-linux-gnu
- uses: Swatinem/rust-cache@v2
with:
key: x86_64-gnu-217
- name: Install system deps
run: |
sudo apt-get update
sudo apt-get install -y \
libfontconfig1-dev libfreetype6-dev libexpat1-dev pkg-config
- uses: mlugg/setup-zig@v2
with:
version: "0.13.0"
- name: Install cargo-zigbuild
run: pip3 install cargo-zigbuild
- name: Build
run: cargo zigbuild --release --target x86_64-unknown-linux-gnu.2.17
- name: Sanity check
run: |
BIN=target/x86_64-unknown-linux-gnu/release/${{ env.BINARY_NAME }}
readelf -W --version-info "$BIN" | grep -o 'GLIBC_[0-9.]*' | sort -Vu | tail -1
nm -D --undefined-only "$BIN" 2>/dev/null | grep -E 'Fc[A-Z].*@FONTCCONFIG_2\.(1[1-9]|[2-9][0-9])' && exit 1 || echo "fontconfig symbols OK"
- uses: actions/upload-artifact@v4
if: ${{ github.event.inputs.upload_artifacts != 'false' }}
with:
name: ${{ env.BINARY_NAME }}-${{ steps.version.outputs.version }}-x86_64-linux-gnu
path: target/x86_64-unknown-linux-gnu/release/${{ env.BINARY_NAME }}
retention-days: 30
build-aarch64-linux:
name: Build aarch64 Linux (gnu)
runs-on: ubuntu-24.04-arm
steps:
- uses: actions/checkout@v4
- name: Compute version
id: version
shell: bash
run: |
# 版本号提取(支持语义化版本,含预发布/构建后缀,如 v0.1.4-beta.1)
if [[ "${{ github.event_name }}" == "push" ]]; then
TAG="${{ github.ref_name }}"
else
TAG="${{ github.event.inputs.release_tag }}"
fi
VER="${TAG#v}"
# 完整 SemVer 匹配:MAJOR.MINOR.PATCH[-pre][+build],未匹配则回退 Cargo.toml
if [[ ! "$VER" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$ ]]; then
VER="$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"([0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?)".*/\1/')"
fi
echo "version=v${VER}" >> "$GITHUB_OUTPUT"
- uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-unknown-linux-gnu
- uses: Swatinem/rust-cache@v2
with:
key: aarch64-gnu-228
- name: Install system deps
run: |
sudo apt-get update
sudo apt-get install -y \
libfontconfig1-dev libfreetype6-dev libexpat1-dev pkg-config
- uses: mlugg/setup-zig@v2
with:
version: "0.13.0"
- name: Install cargo-zigbuild
run: pip3 install cargo-zigbuild
- name: Build
run: cargo zigbuild --release --target aarch64-unknown-linux-gnu.2.28
- name: Sanity check
run: |
BIN=target/aarch64-unknown-linux-gnu/release/${{ env.BINARY_NAME }}
readelf -W --version-info "$BIN" | grep -o 'GLIBC_[0-9.]*' | sort -Vu | tail -1
nm -D --undefined-only "$BIN" 2>/dev/null | grep -E 'Fc[A-Z].*@FONTCCONFIG_2\.(1[1-9]|[2-9][0-9])' && exit 1 || echo "fontconfig symbols OK"
- uses: actions/upload-artifact@v4
if: ${{ github.event.inputs.upload_artifacts != 'false' }}
with:
name: ${{ env.BINARY_NAME }}-${{ steps.version.outputs.version }}-aarch64-linux-gnu
path: target/aarch64-unknown-linux-gnu/release/${{ env.BINARY_NAME }}
retention-days: 30
build-x86_64-windows:
name: Build x86_64 Windows (MSVC)
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Compute version
id: version
shell: bash
run: |
# 版本号提取(支持语义化版本,含预发布/构建后缀,如 v0.1.4-beta.1)
if [[ "${{ github.event_name }}" == "push" ]]; then
TAG="${{ github.ref_name }}"
else
TAG="${{ github.event.inputs.release_tag }}"
fi
VER="${TAG#v}"
# 完整 SemVer 匹配:MAJOR.MINOR.PATCH[-pre][+build],未匹配则回退 Cargo.toml
if [[ ! "$VER" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$ ]]; then
VER="$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"([0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?)".*/\1/')"
fi
echo "version=v${VER}" >> "$GITHUB_OUTPUT"
- uses: dtolnay/rust-toolchain@stable
with:
targets: x86_64-pc-windows-msvc
- uses: Swatinem/rust-cache@v2
with:
key: x86_64-windows-msvc
- name: Install NASM (for some native deps)
run: |
choco install nasm -y
echo "C:\Program Files\NASM" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Build
run: cargo build --release --target x86_64-pc-windows-msvc
- name: Sanity check
run: |
$BIN = "target\x86_64-pc-windows-msvc\release\${{ env.BINARY_NAME }}.exe"
if (Test-Path $BIN) {
Write-Host "Binary exists: $BIN"
$size = (Get-Item $BIN).Length
Write-Host "Binary size: $([math]::Round($size / 1MB, 2)) MB"
} else {
Write-Error "Binary not found: $BIN"
exit 1
}
- uses: actions/upload-artifact@v4
if: ${{ github.event.inputs.upload_artifacts != 'false' }}
with:
name: ${{ env.BINARY_NAME }}-${{ steps.version.outputs.version }}-x86_64-windows-msvc
path: target\x86_64-pc-windows-msvc\release\${{ env.BINARY_NAME }}.exe
retention-days: 30
release:
name: Package and publish GitHub Release
needs:
- build-x86_64-linux
- build-aarch64-linux
- build-x86_64-windows
runs-on: ubuntu-latest
if: >-
github.event_name == 'push' ||
github.event.inputs.upload_artifacts != 'false'
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Compute version
id: version
shell: bash
run: |
# 版本号优先级:
# 1) push tag(如 v0.1.4-beta.1)→ github.ref_name
# 2) 手动触发的 release_tag input(如 v0.1.4-beta.1 或 0.1.4-beta.1)
# 3) 兜底:Cargo.toml 的 package.version
# 统一带 v 前缀(如 v0.1.4-beta.1),支持语义化版本(含预发布/构建后缀)
if [[ "${{ github.event_name }}" == "push" ]]; then
TAG="${{ github.ref_name }}"
else
TAG="${{ github.event.inputs.release_tag }}"
fi
VER="${TAG#v}"
# 完整 SemVer 匹配:MAJOR.MINOR.PATCH[-pre][+build],未匹配则回退 Cargo.toml
if [[ ! "$VER" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$ ]]; then
VER="$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"([0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?)".*/\1/')"
fi
echo "version=v${VER}" >> "$GITHUB_OUTPUT"
echo "Release version: v${VER}"
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Package artifacts
shell: bash
run: |
set -euo pipefail
VER="${{ steps.version.outputs.version }}"
mkdir -p dist
cd artifacts
# x86_64 Linux
tar -czf "../dist/${{ env.BINARY_NAME }}-${VER}-x86_64-linux-gnu.tar.gz" -C "${{ env.BINARY_NAME }}-${VER}-x86_64-linux-gnu" "${{ env.BINARY_NAME }}"
# aarch64 Linux
tar -czf "../dist/${{ env.BINARY_NAME }}-${VER}-aarch64-linux-gnu.tar.gz" -C "${{ env.BINARY_NAME }}-${VER}-aarch64-linux-gnu" "${{ env.BINARY_NAME }}"
# x86_64 Windows
cd "${{ env.BINARY_NAME }}-${VER}-x86_64-windows-msvc"
zip -q "../../dist/${{ env.BINARY_NAME }}-${VER}-x86_64-windows-msvc.zip" "${{ env.BINARY_NAME }}.exe"
cd ../..
# Checksums
cd dist
sha256sum *.tar.gz *.zip > sha256.txt
cat sha256.txt
- name: Publish GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.event.inputs.release_tag != '' && github.event.inputs.release_tag || github.ref_name }}
files: |
dist/*.tar.gz
dist/*.zip
dist/sha256.txt
generate_release_notes: true
fail_on_unmatched_files: true