Skip to content

Create Release and Packages #11

Create Release and Packages

Create Release and Packages #11

Workflow file for this run

name: Create Release and Packages
on:
workflow_dispatch:
inputs:
tag_name:
description: 'Tag name for the release (e.g. v0.1.0)'
required: true
type: string
concurrency:
group: ${{ github.workflow }}-${{ github.event.inputs.tag_name }}
cancel-in-progress: false
permissions:
contents: read
jobs:
build-binaries:
name: Build Binaries
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
use_cross: false
bin_suffix: ""
bin_name: kdc
- target: aarch64-unknown-linux-gnu
os: ubuntu-latest
use_cross: true
bin_suffix: ""
bin_name: kdc
- target: x86_64-apple-darwin
os: macos-latest
use_cross: false
bin_suffix: ""
bin_name: kdc
- target: aarch64-apple-darwin
os: macos-latest
use_cross: false
bin_suffix: ""
bin_name: kdc
- target: x86_64-pc-windows-msvc
os: windows-latest
use_cross: false
bin_suffix: ".exe"
bin_name: kdc.exe
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9 # master
with:
toolchain: stable
targets: ${{ matrix.target }}
- name: Cache Cargo registry and target
uses: Swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2.7.3
with:
key: ${{ matrix.target }}
- name: Install cross
if: matrix.use_cross
uses: taiki-e/install-action@d12e869b89167df346dd0ff65da342d1fb1202fb # v2.53.2
with:
tool: cross
- name: Build release binary
run: |
if [ "${{ matrix.use_cross }}" = "true" ]; then
cross build --release --target ${{ matrix.target }}
else
cargo build --release --target ${{ matrix.target }}
fi
shell: bash
- name: Upload Binary Artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: kdc-${{ matrix.target }}
path: target/${{ matrix.target }}/release/${{ matrix.bin_name }}
retention-days: 1
create-release:
name: Create Release
needs: build-binaries
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
version: ${{ steps.get_version.outputs.version }}
tag_name: ${{ steps.get_version.outputs.tag_name }}
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: Get version from input
id: get_version
env:
TAG_NAME: ${{ inputs.tag_name }}
run: |
# Strict regex check for semver tag starting with 'v'
if [[ ! "$TAG_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+([-+].*)?$ ]]; then
echo "Error: Tag name '$TAG_NAME' is invalid. It must match semver format with a leading 'v' (e.g., v1.0.0, v0.1.0-alpha.1)." >&2
exit 1
fi
VERSION="${TAG_NAME#v}"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "tag_name=${TAG_NAME}" >> "$GITHUB_OUTPUT"
shell: bash
- name: Download all artifacts
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
with:
path: bin-artifacts
- name: Package archives and generate checksums
id: package
run: |
mkdir dist
cd bin-artifacts
for target_dir in ./kdc-*; do
target="${target_dir#./kdc-}"
echo "Packaging archive for $target..."
if [ -f "$target_dir/kdc.exe" ]; then
# Windows
zip -j "../dist/kdc-v${{ steps.get_version.outputs.version }}-${target}.zip" "$target_dir/kdc.exe"
else
# Unix
chmod +x "$target_dir/kdc"
tar -czf "../dist/kdc-v${{ steps.get_version.outputs.version }}-${target}.tar.gz" -C "$target_dir" kdc
fi
done
cd ../dist
sha256sum -- kdc-* > sha256sums.txt
cat sha256sums.txt
shell: bash
- name: Upload archives to release
uses: softprops/action-gh-release@c062e08bd532815e2082a85e87e3ef29c3e6d191 # v2.0.8
with:
files: |
dist/*
tag_name: ${{ steps.get_version.outputs.tag_name }}
draft: false
prerelease: false
generate_release_notes: true
- name: Upload packaging artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: release-dist
path: dist/
retention-days: 1
generate-packages:
name: Generate Packages (APT, RPM, Homebrew)
needs: create-release
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: Download release-dist artifact
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
with:
name: release-dist
path: dist
- name: Download compiled binaries
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
with:
path: bin-artifacts
- name: Generate APT and RPM packages
run: |
chmod +x scripts/package.sh
./scripts/package.sh \
"${{ needs.create-release.outputs.version }}" \
"bin-artifacts/kdc-x86_64-unknown-linux-gnu/kdc" \
"bin-artifacts/kdc-aarch64-unknown-linux-gnu/kdc" \
"dist"
shell: bash
- name: Generate Homebrew Formula
id: generate_formula
run: |
VERSION="${{ needs.create-release.outputs.version }}"
REPO="${{ github.repository }}"
SHA_MAC_AMD64=$(grep "kdc-v${VERSION}-x86_64-apple-darwin.tar.gz" dist/sha256sums.txt | awk '{print $1}')
SHA_MAC_ARM64=$(grep "kdc-v${VERSION}-aarch64-apple-darwin.tar.gz" dist/sha256sums.txt | awk '{print $1}')
SHA_LINUX_AMD64=$(grep "kdc-v${VERSION}-x86_64-unknown-linux-gnu.tar.gz" dist/sha256sums.txt | awk '{print $1}')
SHA_LINUX_ARM64=$(grep "kdc-v${VERSION}-aarch64-unknown-linux-gnu.tar.gz" dist/sha256sums.txt | awk '{print $1}')
# Use a quoted heredoc (<<'EOF') so the shell does not expand Ruby's
# #{...} interpolation syntax. Shell variables are pre-expanded via
# envsubst after the template is written.
cat <<'FORMULA_TEMPLATE' > /tmp/kdc.rb.tpl
class Kdc < Formula
desc "Kubernetes Docker Commander, a project-centric DevOps TUI"
homepage "https://github.com/${REPO}"
version "${VERSION}"
if OS.mac?
if Hardware::CPU.arm?
url "https://github.com/${REPO}/releases/download/v${VERSION}/kdc-v${VERSION}-aarch64-apple-darwin.tar.gz"
sha256 "${SHA_MAC_ARM64}"
else
url "https://github.com/${REPO}/releases/download/v${VERSION}/kdc-v${VERSION}-x86_64-apple-darwin.tar.gz"
sha256 "${SHA_MAC_AMD64}"
end
elsif OS.linux?
if Hardware::CPU.arm?
url "https://github.com/${REPO}/releases/download/v${VERSION}/kdc-v${VERSION}-aarch64-unknown-linux-gnu.tar.gz"
sha256 "${SHA_LINUX_ARM64}"
else
url "https://github.com/${REPO}/releases/download/v${VERSION}/kdc-v${VERSION}-x86_64-unknown-linux-gnu.tar.gz"
sha256 "${SHA_LINUX_AMD64}"
end
end
def install
bin.install "kdc"
end
test do
system "#{bin}/kdc", "--version"
end
end
FORMULA_TEMPLATE
# Substitute only the shell variables we care about; Ruby's #{...} is
# left untouched because envsubst only replaces $VAR / ${VAR} forms.
VERSION="$VERSION" REPO="$REPO" \
SHA_MAC_ARM64="$SHA_MAC_ARM64" SHA_MAC_AMD64="$SHA_MAC_AMD64" \
SHA_LINUX_ARM64="$SHA_LINUX_ARM64" SHA_LINUX_AMD64="$SHA_LINUX_AMD64" \
envsubst '${VERSION} ${REPO} ${SHA_MAC_ARM64} ${SHA_MAC_AMD64} ${SHA_LINUX_ARM64} ${SHA_LINUX_AMD64}' \
< /tmp/kdc.rb.tpl > dist/kdc.rb
echo "Formula generated:"
cat dist/kdc.rb
shell: bash
- name: Update existing release with packages
uses: softprops/action-gh-release@c062e08bd532815e2082a85e87e3ef29c3e6d191 # v2.0.8
with:
files: |
dist/*.deb
dist/*.rpm
dist/kdc.rb
tag_name: ${{ needs.create-release.outputs.tag_name }}
append_body: true
- name: Update Homebrew Tap Repository
env:
TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
run: |
if [ -z "$TAP_TOKEN" ]; then
echo "Warning: HOMEBREW_TAP_TOKEN is not configured. Skipping automated Homebrew formula update."
echo "The generated Homebrew formula was uploaded as a release asset (kdc.rb)."
exit 0
fi
echo "Configuring git..."
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
GITHUB_REPO="${{ github.repository }}"
GITHUB_OWNER="${GITHUB_REPO%/*}"
echo "Cloning homebrew tap owned by ${GITHUB_OWNER}..."
git clone "https://${TAP_TOKEN}@github.com/${GITHUB_OWNER}/homebrew-tap.git" homebrew-tap
mkdir -p homebrew-tap/Formula
cp dist/kdc.rb homebrew-tap/Formula/kdc.rb
cd homebrew-tap
git add Formula/kdc.rb
if git diff-index --quiet HEAD; then
echo "No changes in Homebrew formula."
else
git commit -m "Bump kdc to v${{ needs.create-release.outputs.version }}"
git push origin main
echo "Successfully updated Homebrew Formula in tap."
fi
shell: bash