Skip to content

Remove experimental guard from downstream resource copy (#5207) #399

Remove experimental guard from downstream resource copy (#5207)

Remove experimental guard from downstream resource copy (#5207) #399

Workflow file for this run

# Fleet release workflow
name: Fleet release
on:
push:
tags:
- v**
permissions:
contents: write
id-token: write # this is important, it's how we authenticate with Vault
env:
GOARCH: amd64
CGO_ENABLED: 0
RELEASE_TAG: ${{ github.ref_name }}
jobs:
build-fleet:
runs-on: runs-on,runner=8cpu-linux-x64,mem=16,run-id=${{ github.run_id }}
permissions:
contents: write
id-token: write
pull-requests: read
checks: read
env:
IS_HOTFIX: ${{ contains(github.ref, '-hotfix-') }}
if: github.repository == 'rancher/fleet'
steps:
- name: Check out Fleet
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- name: Verify CI passed on tagged commit
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
run: ./.github/scripts/verify-ci-on-commit.sh
- name: Set up Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version-file: 'go.mod'
cache: false
- name: Set up QEMU
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
with:
# renovate: datasource=docker depName=tonistiigi/binfmt extractVersion=^qemu-v(?<version>.+)$
image: tonistiigi/binfmt:qemu-v10.2.1-65@sha256:d3b963f787999e6c0219a48dba02978769286ff61a5f4d26245cb6a6e5567ea3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
- name: Install Cosign
uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1
- name: Install Slsactl
uses: rancherlabs/slsactl/actions/install-slsactl@132f4c15b16537cf031aae50c788fdad1a8fe723 # v0.1.33
with:
# renovate: datasource=github-tags depName=rancherlabs/slsactl
version: v0.1.33
- name: "Read Vault Secrets"
uses: rancher-eio/read-vault-secrets@0da85151ad1f19ed7986c41587e45aac1ace74b6 # v3
with:
secrets: |
secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials username | DOCKER_USERNAME ;
secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials password | DOCKER_PASSWORD ;
secret/data/github/repo/${{ github.repository }}/rancher-prime-stg-registry/credentials username | STAGE_REGISTRY_USERNAME ;
secret/data/github/repo/${{ github.repository }}/rancher-prime-stg-registry/credentials password | STAGE_REGISTRY_PASSWORD ;
secret/data/github/repo/${{ github.repository }}/rancher-prime-stg-registry/credentials registry | STAGE_REGISTRY ;
secret/data/github/repo/${{ github.repository }}/rancher-prime-registry/credentials registry | PRIME_REGISTRY ;
- name: Log into Docker Container registry
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
if: ${{ env.IS_HOTFIX == 'false' }}
with:
username: ${{ env.DOCKER_USERNAME }}
password: ${{ env.DOCKER_PASSWORD }}
- name: Log into Staging registry
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
username: ${{ env.STAGE_REGISTRY_USERNAME }}
password: ${{ env.STAGE_REGISTRY_PASSWORD }}
registry: ${{ env.STAGE_REGISTRY }}
- name: Setup goreleaser
shell: bash
run: |
set -euo pipefail
OS="Linux"
if [[ ${RUNNER_OS} != "Linux" ]]; then
echo "Unsupported OS: ${RUNNER_OS}"
exit 1
fi
# renovate: datasource=github-releases depName=goreleaser/goreleaser
GORELEASER_VERSION="v2.15.4"
# renovate: datasource=github-release-attachments depName=goreleaser/goreleaser digestVersion=v2.15.4
GORELEASER_CHECKSUM_amd64="aae00c71a4a6d55e08cce9273a1516bdce33c1e07cffb7e502fa6fec4377dede"
ARCH=$(uname -m)
CHECKSUM="${GORELEASER_CHECKSUM_amd64}"
if [[ "${ARCH}" != "x86_64" ]]; then
echo "Unsupported architecture: ${ARCH}"
exit 1
fi
FILE="goreleaser_${OS}_${ARCH}.tar.gz"
echo "Installing ${FILE}"
curl --fail --location -O "https://github.com/goreleaser/goreleaser/releases/download/${GORELEASER_VERSION}/${FILE}"
echo "${CHECKSUM} ${FILE}" | sha256sum -c
tar -xf "${FILE}" goreleaser
mkdir -p "${HOME}/.local/bin"
install -m 755 goreleaser "${HOME}/.local/bin/goreleaser"
echo "${HOME}/.local/bin" >> "${GITHUB_PATH}"
rm -f "${FILE}" goreleaser
- name: Run GoReleaser
id: goreleaser
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GORELEASER_CURRENT_TAG: ${{ env.RELEASE_TAG }}
STAGE_REGISTRY: ${{ env.STAGE_REGISTRY }}
PRIME_REGISTRY: ${{ env.PRIME_REGISTRY }}
shell: bash
run: |
set -euo pipefail
goreleaser release --clean --draft --verbose
if [[ ! -f dist/metadata.json ]] || [[ ! -s dist/metadata.json ]]; then
echo "ERROR: dist/metadata.json not found or empty after GoReleaser run"
exit 1
fi
if [[ ! -f dist/artifacts.json ]] || [[ ! -s dist/artifacts.json ]]; then
echo "ERROR: dist/artifacts.json not found or empty after GoReleaser run"
exit 1
fi
echo "metadata=$(tr -d '\n\r' < dist/metadata.json)" >> "${GITHUB_OUTPUT}"
echo "artifacts=$(tr -d '\n\r' < dist/artifacts.json)" >> "${GITHUB_OUTPUT}"
- name: Attest provenance
shell: bash
env:
STAGE_REGISTRY: ${{ env.STAGE_REGISTRY }}
run: |
set -euo pipefail
if [[ ! -f dist/digests.txt ]] || [[ ! -s dist/digests.txt ]]; then
echo "ERROR: dist/digests.txt not found or empty"
exit 1
fi
# Extract staging images (exclude platform-specific tags)
# Format: <digest> <image:tag> → only staging registry images
staging_images=$(grep -v -- '-linux-' dist/digests.txt | \
awk '{print "sha256:" $1, $NF}' | \
grep -F -- "${STAGE_REGISTRY}" || true)
if [[ -z "$staging_images" ]]; then
echo "ERROR: No staging images found"
exit 1
fi
echo "=== Staging images for attestation ==="
echo "$staging_images"
echo ""
max_retries=3
while read -r digest image_ref; do
echo ""
echo "Attesting: ${image_ref}"
echo " Digest: ${digest}"
for platform in "linux/amd64" "linux/arm64"; do
echo " Platform ${platform}..."
prov_file="provenance_${platform/\//_}.json"
# Retry download
for ((i=1; i<=max_retries; i++)); do
echo " Attempt ${i}/${max_retries}..."
if slsactl download provenance --format=slsav1 --platform="${platform}" "${image_ref}@${digest}" > "${prov_file}"; then
echo " ✓ Downloaded provenance"
break
fi
if [ "${i}" -eq "${max_retries}" ]; then
echo "ERROR: Failed to download provenance for ${platform} of ${image_ref} after ${max_retries} attempts"
exit 1
fi
echo " Waiting before retry..."
sleep 5
done
# Attest (must succeed)
if ! cosign attest --yes --predicate "${prov_file}" --type slsaprovenance1 "${image_ref}@${digest}" 2>&1; then
echo "ERROR: cosign attest failed for ${platform} of ${image_ref}"
rm -f "${prov_file}"
exit 1
fi
echo " ✓ Attested"
rm -f "${prov_file}"
done
done <<< "$staging_images"
echo ""
echo "✓ Provenance attestation completed for all images"
- name: Add charts to branch
if: ${{ env.IS_HOTFIX == 'false' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
version=$(jq -r '.version' <<< '${{ steps.goreleaser.outputs.metadata }}')
branch_version=v$(cut -d'.' -f1,2 <<< "$version")
charts_branch=charts/$branch_version
if [ ! -e ~/.gitconfig ]; then
git config --global user.name "fleet-bot"
git config --global user.email fleet@suse.de
fi
echo "publishing helm chart in the branch $charts_branch"
if ! git ls-remote --exit-code --heads origin "$charts_branch"; then
git checkout --orphan "$charts_branch"
git rm -rf .
echo "# Fleet Helm Charts for $branch_version versions" > README.md
echo "The documentation is centralized in a unique place, checkout https://fleet.rancher.io/." >> README.md
git checkout origin/main -- LICENSE .gitignore
git add README.md LICENSE .gitignore
git commit -m "Initial commit for $charts_branch"
else
git checkout .
git checkout "$charts_branch"
fi
mkdir -p charts
find .charts/ -name '*.tgz' -exec tar -xf {} -C charts/ \;
git add charts/**/*
git commit -m "Update charts to version $version"
git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@github.com/${{ github.repository }}.git"
git push origin "$charts_branch"
- name: Publish Release
if: ${{ env.IS_HOTFIX == 'false' }}
run: gh release edit "${RELEASE_TAG}" --draft=false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
dispatch-charts-bump:
permissions:
contents: read
id-token: write
runs-on: ubuntu-latest
timeout-minutes: 10
needs: build-fleet
# Skip hotfix releases; they follow a separate process.
if: github.repository == 'rancher/fleet' && !contains(github.ref, '-hotfix-')
steps:
- name: Read App Secrets
uses: rancher-eio/read-vault-secrets@0da85151ad1f19ed7986c41587e45aac1ace74b6 # v3
with:
secrets: |
secret/data/github/repo/${{ github.repository }}/github/workflow-dispatcher/app-credentials appId | APP_ID ;
secret/data/github/repo/${{ github.repository }}/github/workflow-dispatcher/app-credentials privateKey | PRIVATE_KEY
- name: Create App Token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
id: app-token
with:
app-id: ${{ env.APP_ID }}
private-key: ${{ env.PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
repositories: charts
permission-actions: write
- name: Dispatch to rancher/charts
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
FLEET_TAG: ${{ github.ref_name }}
run: |
set -euo pipefail
if [[ "$FLEET_TAG" =~ ^v([0-9]+)\.([0-9]+)([.-].*)?$ ]]; then
fleet_minor="${BASH_REMATCH[2]}"
else
echo "Error: unexpected Fleet tag format '${FLEET_TAG}'. Expected tags starting with v<major>.<minor>." >&2
exit 1
fi
if (( fleet_minor < 1 )); then
echo "Error: Fleet tag '${FLEET_TAG}' has minor version ${fleet_minor}; cannot derive a valid rancher/charts target branch." >&2
exit 1
fi
rancher_minor=$((fleet_minor - 1))
target_branch="dev-v2.${rancher_minor}"
echo "Dispatching auto-bump for Fleet ${FLEET_TAG} to rancher/charts branch ${target_branch}"
gh workflow run "Manual Trigger for Auto Bump" \
--repo rancher/charts \
--ref "$target_branch" \
-F chart=fleet \
-F branch="$target_branch" \
-F multi-rc=true