Skip to content

Fleet Release

Fleet Release #243

Workflow file for this run

name: Fleet Release
# =============================================================================
# WORKFLOW CONFIGURATION
# =============================================================================
permissions:
contents: write
actions: write
pull-requests: write
attestations: write
id-token: write
packages: write
on:
push:
branches: [main]
paths-ignore:
# - '.github/**'
- "**/*.md"
workflow_dispatch:
inputs:
version:
description: "Version to Release (x.y.z). Leave empty for auto patch bump."
required: false
type: string
default: ''
concurrency:
group: ${{ github.event_name == 'push' && 'fleet-release-latest' || 'fleet-release-manual' }}
cancel-in-progress: true
env:
REGISTRY: ghcr.io
BINARY_NAME: fleet
# =============================================================================
# JOBS
# =============================================================================
jobs:
version:
name: Resolve Version
uses: ./.github/workflows/version.yml
with:
version: ${{ inputs.version }}
changes:
name: Detect Changes
uses: ./.github/workflows/changes.yaml
if: |
github.event_name == 'workflow_dispatch' ||
github.event_name == 'push'
build_client:
name: "Build Client (${{ matrix.os }})"
needs: [version, changes]
runs-on: ${{ matrix.os }}
if: |
(github.event_name == 'push' && fromJSON(needs.changes.outputs.changes || '{}').client == 'true') ||
(github.event_name == 'workflow_dispatch' && needs.version.outputs.version != '')
defaults:
run:
shell: bash
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.changes.outputs.clients_matrix) }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Prepare Build tools
uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
- name: Compile Client for ${{ matrix.go_os }}
run: |
if [[ "${{ matrix.os }}" == "macos-latest" ]]; then
rm -rf ./build_target
mkdir -p ./build_target
architectures=($(echo '${{ toJSON(matrix.go_arch) }}' | jq -r '.[]'))
for arch in "${architectures[@]}"; do
echo "Building for ${{ matrix.go_os }}/${arch}"
env GOARCH=${arch} go build -o ./build_target/fleet-${arch} ./orbit/cmd/orbit
done
ls -la ./build_target
echo "Create ${{ matrix.artifact_name }}"
mkdir -p ./artifacts
arch0=${architectures[0]}
arch1=${architectures[1]}
lipo -create ./build_target/fleet-${arch0} ./build_target/fleet-${arch1} -output ./artifacts/${{ env.BINARY_NAME }}
lipo -info ./artifacts/${{ env.BINARY_NAME }}
ls -la ./artifacts
rm -rf ./build_target
elif [[ "${{ matrix.os }}" == "windows-latest" ]]; then
mkdir -p ./artifacts
env GOARCH=${{ matrix.go_arch }} go build -o ./artifacts/${{ env.BINARY_NAME }}.exe ./orbit/cmd/orbit
ls -la ./artifacts
fi
- name: Sign MacOS package
if: runner.os == 'macOS'
uses: ./.github/steps/sign-macos-package
with:
apple_certificate_p12: ${{ secrets.APPLE_CERTIFICATE_P12 }}
apple_certificate_password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
apple_developer_id: ${{ secrets.APPLE_DEVELOPER_ID }}
apple_id_username: ${{ secrets.APPLE_ID_USERNAME }}
apple_id_password: ${{ secrets.APPLE_ID_PASSWORD }}
apple_team_id: ${{ secrets.APPLE_TEAM_ID }}
binary_name: ${{ env.BINARY_NAME }}
- name: Sign Windows package
if: runner.os == 'Windows'
uses: ./.github/steps/sign-windows-package
with:
azure_tenant_id: ${{ secrets.AZURE_TENANT_ID }}
azure_client_id: ${{ secrets.AZURE_CLIENT_ID }}
azure_client_secret: ${{ secrets.AZURE_CLIENT_SECRET }}
signing_endpoint: ${{ secrets.AZURE_SIGNING_ENDPOINT }}
code_signing_account_name: ${{ secrets.AZURE_CODE_SIGNING_ACCOUNT_NAME }}
certificate_profile_name: ${{ secrets.AZURE_CERTIFICATE_PROFILE_NAME }}
binary_path: artifacts/${{ env.BINARY_NAME }}.exe
- name: Upload client artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact_name }}
path: |
artifacts/
if-no-files-found: warn
retention-days: 7
compression-level: 9
build:
name: "Build Fleet"
needs: [version, changes]
runs-on: ubuntu-latest
if: |
(github.event_name == 'push' && fromJSON(needs.changes.outputs.changes || '{}').server == 'true') ||
(github.event_name == 'workflow_dispatch' && needs.version.outputs.version != '')
steps:
- name: Harden Runner
uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: "go.mod"
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version-file: package.json
- name: Install JS Dependencies
run: for i in 1 2 3; do make deps-js && break || sleep 15; done
- name: Install ARM64 cross-compiler
run: sudo apt-get update && sudo apt-get install -y gcc-aarch64-linux-gnu
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Install GoReleaser
uses: goreleaser/goreleaser-action@v6
with:
install-only: true
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create local tag
run: git tag -f v9.9.9
- name: Run GoReleaser
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REGISTRY: ${{ env.REGISTRY }}
GITHUB_REPOSITORY: ${{ github.repository }}
DOCKER_TAG: ${{ needs.version.outputs.version }}
DOCKER_PUSH: "true"
run: goreleaser release --clean
build_helm:
name: "Build Helm Chart"
needs: [version, changes]
runs-on: ubuntu-latest
if: |
(github.event_name == 'push' && fromJSON(needs.changes.outputs.changes || '{}').helm == 'true') ||
(github.event_name == 'workflow_dispatch' && needs.version.outputs.version != '')
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Helm
uses: azure/setup-helm@v4
- name: Push Chart
uses: appany/helm-oci-chart-releaser@v0.5.0
with:
name: fleet
repository: ${{ github.repository }}/helm-charts
tag: ${{ needs.version.outputs.version == 'latest' && '9.9.9' || needs.version.outputs.version }}
path: ./charts/fleet
registry: ${{ env.REGISTRY }}
registry_username: ${{ github.actor }}
registry_password: ${{ secrets.GITHUB_TOKEN }}
release:
name: "Create Release"
needs: [version, changes, build, build_client, build_helm]
runs-on: ubuntu-latest
if: ${{ !failure() && !cancelled() }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: release-artifacts
continue-on-error: true
- name: Prepare release artifacts
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -e
mkdir -p final-artifacts/clients
gh release download latest --pattern "*.tar.gz" --pattern "*.zip" --dir final-artifacts/clients || true
# macOS
if [ -d "release-artifacts/fleet-mac-universal" ]; then
tar -czf "final-artifacts/clients/fleet-macos-universal.tar.gz" \
-C "release-artifacts/fleet-mac-universal" fleet
fi
# Windows
if [ -d "release-artifacts/fleet-windows-amd64" ]; then
(cd "release-artifacts/fleet-windows-amd64" && \
zip "${GITHUB_WORKSPACE}/final-artifacts/clients/fleet-windows-amd64.zip" fleet.exe)
fi
ls -lh final-artifacts/clients/
for f in fleet-macos-universal.tar.gz fleet-windows-amd64.zip; do
[ -s "final-artifacts/clients/$f" ] || { echo "::error::missing client assets: $f"; exit 1; }
done
- name: Generate release header
run: |
VERSION="${{ needs.version.outputs.version }}"
IMAGES=$(echo '${{ needs.changes.outputs.images_matrix }}' | jq -r '.[] | "- `${{ env.REGISTRY }}/${{ github.repository }}/\(.name):'"${VERSION}"'`"')
cat > RELEASE_HEADER.md <<EOF
## Images
${IMAGES}
## Fleet Clients
- **macOS** (Universal): \`fleet-macos-universal.tar.gz\`
- **Windows** (amd64): \`fleet-windows-amd64.zip\`
## Helm Chart
- \`oci://${{ env.REGISTRY }}/${{ github.repository }}/helm-charts/fleet:${VERSION}\`
EOF
- name: Delete existing latest release
if: ${{ github.event_name == 'push' }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh release delete latest --yes --cleanup-tag || true
- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.version.outputs.version }}
name: "🦩 ${{ needs.version.outputs.version }}"
draft: false
prerelease: ${{ github.event_name == 'push' }}
token: ${{ secrets.GITHUB_TOKEN }}
body_path: RELEASE_HEADER.md
fail_on_unmatched_files: true
files: |
final-artifacts/clients/*.zip
final-artifacts/clients/*.tar.gz