Files
mikusays-c/.github/workflows/release.yml
T

266 lines
9.0 KiB
YAML

name: Cross-platform Build
on:
push:
tags: [ 'v*' ]
workflow_dispatch:
permissions:
contents: write
jobs:
extract-version:
name: Extract Version
runs-on: ubuntu-latest
outputs:
version: ${{ steps.get_version.outputs.version }}
version_valid: ${{ steps.validate_version.outputs.valid }}
steps:
- uses: actions/checkout@v4
- name: Get version from Cargo.toml
id: get_version
run: |
VERSION=$(grep '^version =' Cargo.toml | sed -E 's/version = "([^"]+)"/\1/')
echo "Extracted version: $VERSION"
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Validate SemVer
id: validate_version
run: |
VERSION=${{ steps.get_version.outputs.version }}
# Comprehensive SemVer validation regex
# Supports: MAJOR.MINOR.PATCH-PRERELEASE+BUILD
# Where PRERELEASE can be: alpha, beta, rc.1, etc.
# Where BUILD can be: build.123, sha.abc123, etc.
if [[ ! $VERSION =~ ^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?(\+([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?$ ]]; then
echo "Error: Version '$VERSION' is not a valid SemVer string"
echo "valid=false" >> $GITHUB_OUTPUT
exit 1
else
echo "Version '$VERSION' is valid SemVer"
echo "valid=true" >> $GITHUB_OUTPUT
fi
build-windows:
name: Build Windows
runs-on: windows-latest
needs: extract-version
strategy:
matrix:
target:
- x86_64-pc-windows-msvc
- aarch64-pc-windows-msvc
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Build
run: cargo build --release --target ${{ matrix.target }}
- name: Prepare artifact
run: |
mkdir artifacts
$arch = "${{ matrix.target }}".Split('-')[0]
$version = "${{ needs.extract-version.outputs.version }}"
copy "target\${{ matrix.target }}\release\mikusays.exe" "artifacts\mikusays-windows-$arch-$version.exe"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: mikusays-windows-${{ matrix.target }}
path: artifacts\*
build-linux:
name: Build Linux
runs-on: ubuntu-latest
needs: extract-version
strategy:
matrix:
include:
- target: x86_64-unknown-linux-gnu
arch: x64
- target: aarch64-unknown-linux-gnu
arch: arm64
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Install cross-compilation tools
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
run: cargo build --release --target ${{ matrix.target }}
- name: Strip binary
run: |
if [[ "${{ matrix.target }}" == "aarch64-unknown-linux-gnu" ]]; then
aarch64-linux-gnu-strip target/${{ matrix.target }}/release/mikusays
else
strip target/${{ matrix.target }}/release/mikusays
fi
- name: Prepare artifact
run: |
mkdir -p artifacts staging
version="${{ needs.extract-version.outputs.version }}"
stem="mikusays-linux-${{ matrix.arch }}-$version"
cp target/${{ matrix.target }}/release/mikusays "staging/$stem"
chmod 755 "staging/$stem"
tar -C staging -czf "artifacts/$stem.tar.gz" "$stem"
- name: Verify artifact
run: |
version="${{ needs.extract-version.outputs.version }}"
stem="mikusays-linux-${{ matrix.arch }}-$version"
extract_dir="$(mktemp -d)"
tar -tzf "artifacts/$stem.tar.gz" | grep -Fx "$stem"
tar -xzf "artifacts/$stem.tar.gz" -C "$extract_dir"
test -x "$extract_dir/$stem"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: mikusays-linux-${{ matrix.arch }}
path: artifacts/*
build-macos:
name: Build macOS
runs-on: macos-latest
needs: extract-version
strategy:
matrix:
include:
- target: x86_64-apple-darwin
arch: x64
- target: aarch64-apple-darwin
arch: arm64
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Build
run: cargo build --release --target ${{ matrix.target }}
- name: Strip binary
run: strip target/${{ matrix.target }}/release/mikusays
- name: Prepare artifact
run: |
mkdir -p artifacts staging
version="${{ needs.extract-version.outputs.version }}"
stem="mikusays-macos-${{ matrix.arch }}-$version"
cp target/${{ matrix.target }}/release/mikusays "staging/$stem"
chmod 755 "staging/$stem"
tar -C staging -czf "artifacts/$stem.tar.gz" "$stem"
- name: Verify artifact
run: |
version="${{ needs.extract-version.outputs.version }}"
stem="mikusays-macos-${{ matrix.arch }}-$version"
extract_dir="$(mktemp -d)"
tar -tzf "artifacts/$stem.tar.gz" | grep -Fx "$stem"
tar -xzf "artifacts/$stem.tar.gz" -C "$extract_dir"
test -x "$extract_dir/$stem"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: mikusays-macos-${{ matrix.arch }}
path: artifacts/*
create-release:
name: Create Release
runs-on: ubuntu-latest
needs: [extract-version, build-windows, build-linux, build-macos]
if: startsWith(github.ref, 'refs/tags/v') && needs.extract-version.outputs.version_valid == 'true'
steps:
- uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: Display structure of downloaded files
run: ls -R artifacts
- name: Create Release
uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
with:
files: artifacts/mikusays-*
draft: false
prerelease: false
generate_release_notes: true
body: |
## Downloads
### Windows
- **x64**: `mikusays-windows-x86_64-${{ needs.extract-version.outputs.version }}.exe`
- **ARM64**: `mikusays-windows-aarch64-${{ needs.extract-version.outputs.version }}.exe`
### Windows Installer
- **Any**: `mikusays-windows-inst-any-${{ needs.extract-version.outputs.version }}.exe`
### Linux (tar.gz)
- **x64**: `mikusays-linux-x64-${{ needs.extract-version.outputs.version }}.tar.gz`
- **ARM64**: `mikusays-linux-arm64-${{ needs.extract-version.outputs.version }}.tar.gz`
### Debian Package
- **x64 Debian Package**: `mikusays-debian-x86_64-${{ needs.extract-version.outputs.version }}.deb`
- **ARM64 Debian Package**: `mikusays-debian-aarch64-${{ needs.extract-version.outputs.version }}.deb`
### RedHat (RPM) Package
- **x64 RPM Package**: `mikusays-redhat-x86_64-${{ needs.extract-version.outputs.version }}.rpm`
- **ARM64 RPM Package**: `mikusays-redhat-aarch64-${{ needs.extract-version.outputs.version }}.rpm`
### Repository for Debian / Ubuntu / Fedora / RHEL / CentOS
Information on how to add it available here https://apt.xxanqw.pp.ua
### macOS (tar.gz)
- **Intel (x64)**: `mikusays-macos-x64-${{ needs.extract-version.outputs.version }}.tar.gz`
- **Apple Silicon (ARM64)**: `mikusays-macos-arm64-${{ needs.extract-version.outputs.version }}.tar.gz`
## Usage
```bash
# Download and extract the appropriate archive on Linux/macOS:
archive="mikusays-linux-x64-${{ needs.extract-version.outputs.version }}.tar.gz"
tar -xzf "$archive"
# Run the program:
"./${archive%.tar.gz}" "Hello, World!"
# If Gatekeeper blocks an unsigned macOS binary:
xattr -d com.apple.quarantine "./${archive%.tar.gz}"
```
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Notify package managers
env:
GH_TOKEN: ${{ secrets.RELEASE_TOKEN }}
RELEASE_TAG: v${{ needs.extract-version.outputs.version }}
run: |
for repository in xxanqw/scoop-bucket xxanqw/homebrew-mikusays; do
if ! gh api --method POST "repos/$repository/dispatches" \
--raw-field event_type=new-release \
--field "client_payload[tag_name]=$RELEASE_TAG"; then
echo "::warning::Could not dispatch $repository; its four-hour schedule will pick up the release. Check RELEASE_TOKEN if immediate updates are required."
fi
done