name: Publish and Release
on:
push:
tags: ["v*"]
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
jobs:
ci:
uses: ./.github/workflows/ci.yml
binary-release-assets:
name: Build binary release assets
runs-on: ${{ matrix.os }}
needs: ci
permissions:
contents: write
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
archive_ext: tar.gz
asset_suffix: linux-amd64
binary_name: greentic-deployer
- os: ubuntu-24.04-arm
target: aarch64-unknown-linux-gnu
archive_ext: tar.gz
asset_suffix: linux-arm64
binary_name: greentic-deployer
- os: windows-latest
target: x86_64-pc-windows-msvc
archive_ext: zip
asset_suffix: windows-amd64
binary_name: greentic-deployer.exe
- os: windows-11-arm
target: aarch64-pc-windows-msvc
archive_ext: zip
asset_suffix: windows-arm64
binary_name: greentic-deployer.exe
- os: macos-15-intel
target: x86_64-apple-darwin
archive_ext: tar.gz
asset_suffix: macos-amd64
binary_name: greentic-deployer
- os: macos-15
target: aarch64-apple-darwin
archive_ext: tar.gz
asset_suffix: macos-arm64
binary_name: greentic-deployer
steps:
- uses: actions/checkout@v4
- name: Read crate version
id: version
shell: bash
run: |
set -euo pipefail
version=$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -n 1)
if [ -z "$version" ]; then
echo "Failed to read version from Cargo.toml" >&2
exit 1
fi
echo "value=$version" >> "$GITHUB_OUTPUT"
echo "tag=v$version" >> "$GITHUB_OUTPUT"
- uses: dtolnay/rust-toolchain@1.95.0
with:
toolchain: 1.95.0
targets: ${{ matrix.target }}
- uses: Swatinem/rust-cache@v2
- name: Build release binary
run: cargo build --locked --release --target ${{ matrix.target }}
- name: Package Unix asset
if: matrix.archive_ext == 'tar.gz'
shell: bash
env:
ASSET_BASENAME: greentic-deployer-${{ matrix.target }}-${{ steps.version.outputs.tag }}
run: |
set -euo pipefail
mkdir "$ASSET_BASENAME"
cp "target/${{ matrix.target }}/release/${{ matrix.binary_name }}" "$ASSET_BASENAME/"
tar -czf "${ASSET_BASENAME}.tar.gz" "$ASSET_BASENAME"
- name: Package Windows ARM asset
if: matrix.archive_ext == 'zip'
shell: pwsh
env:
ASSET_BASENAME: greentic-deployer-${{ matrix.target }}-${{ steps.version.outputs.tag }}
run: |
New-Item -ItemType Directory -Path $env:ASSET_BASENAME | Out-Null
Copy-Item "target/${{ matrix.target }}/release/${{ matrix.binary_name }}" "$env:ASSET_BASENAME/"
Compress-Archive -Path $env:ASSET_BASENAME -DestinationPath "$env:ASSET_BASENAME.zip"
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: greentic-deployer-${{ matrix.target }}-${{ steps.version.outputs.tag }}
path: greentic-deployer-${{ matrix.target }}-${{ steps.version.outputs.tag }}.${{ matrix.archive_ext }}
publish-version-release:
name: Publish version release
runs-on: ubuntu-latest
needs: binary-release-assets
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Read crate version
id: version
shell: bash
run: |
set -euo pipefail
version=$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -n 1)
if [ -z "$version" ]; then
echo "Failed to read version from Cargo.toml" >&2
exit 1
fi
echo "value=$version" >> "$GITHUB_OUTPUT"
echo "tag=v$version" >> "$GITHUB_OUTPUT"
- uses: actions/download-artifact@v4
with:
pattern: greentic-deployer-*-${{ steps.version.outputs.tag }}
path: dist
merge-multiple: true
- name: Publish GitHub release assets
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ steps.version.outputs.value }}
target_commitish: ${{ github.sha }}
name: v${{ steps.version.outputs.value }}
prerelease: false
make_latest: true
fail_on_unmatched_files: true
overwrite_files: true
files: |
dist/*.tar.gz
dist/*.zip
gtpack-publish:
runs-on: ubuntu-latest
needs: ci
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@1.95.0
with:
toolchain: 1.95.0
- uses: Swatinem/rust-cache@v2
- name: Install cargo-binstall
uses: cargo-bins/cargo-binstall@main
- name: Add Cargo bin to PATH
run: echo "${CARGO_HOME:-$HOME/.cargo}/bin" >> "$GITHUB_PATH"
- name: Install Greentic fixture tools
run: ci/ensure_fixture_tools.sh
- uses: oras-project/setup-oras@v1
- name: Build fixture gtpacks
id: build-gtpacks
run: |
set -euo pipefail
cargo run --features internal-tools --bin build_fixture_gtpacks | tee /tmp/build_fixture_gtpacks.log
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Publish gtpacks to GHCR
env:
GHCR_NAMESPACE: ghcr.io/${{ github.repository_owner }}/packs/deployer
REVISION: ${{ github.sha }}
run: |
set -euo pipefail
mapfile -t pack_lines < <(grep $'^PACK\t' /tmp/build_fixture_gtpacks.log || true)
if [ "${#pack_lines[@]}" -eq 0 ]; then
echo "No PACK metadata found in build output"
exit 1
fi
for pack_line in "${pack_lines[@]}"; do
IFS=$'\t' read -r _ pack_id pack_version pack_path <<<"${pack_line}"
pack_file="$(basename "$pack_path")"
version_ref="${GHCR_NAMESPACE}/${pack_id}:${pack_version}"
latest_ref="${GHCR_NAMESPACE}/${pack_id}:latest"
stable_ref="${GHCR_NAMESPACE}/${pack_id}:stable"
echo "Publishing ${pack_file} -> ${version_ref}"
oras push "${version_ref}" \
--artifact-type application/vnd.greentic.gtpack.v1 \
--annotation "org.opencontainers.image.title=${pack_file}" \
--annotation "org.opencontainers.image.revision=${REVISION}" \
"${pack_path}:application/vnd.greentic.gtpack.layer.v1+tar"
echo "Publishing ${pack_file} -> ${latest_ref}"
oras push "${latest_ref}" \
--artifact-type application/vnd.greentic.gtpack.v1 \
--annotation "org.opencontainers.image.title=${pack_file}" \
--annotation "org.opencontainers.image.revision=${REVISION}" \
"${pack_path}:application/vnd.greentic.gtpack.layer.v1+tar"
echo "Publishing ${pack_file} -> ${stable_ref}"
oras push "${stable_ref}" \
--artifact-type application/vnd.greentic.gtpack.v1 \
--annotation "org.opencontainers.image.title=${pack_file}" \
--annotation "org.opencontainers.image.revision=${REVISION}" \
"${pack_path}:application/vnd.greentic.gtpack.layer.v1+tar"
done
publish_crates:
name: Publish to crates.io
needs: [publish-version-release]
permissions:
contents: read
uses: greenticai/.github/.github/workflows/crates-publish.yml@main
with:
crates: "greentic-deployer"
secrets: inherit