mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-10-17 10:09:05 +02:00
ci: build each release once from its tag and publish it as a draft (#2754)
Co-authored-by: Claude <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude
parent
1e48663824
commit
4af7012048
+60
-20
@@ -1,8 +1,15 @@
|
||||
name: CI
|
||||
|
||||
# Pull requests run the Windows tests only when Go sources, modules, test data,
|
||||
# tools/, the configuration examples or this workflow change. Pushes, tags and
|
||||
# releases always run them.
|
||||
# tools/, the configuration examples or this workflow change. Pushes always run
|
||||
# them.
|
||||
#
|
||||
# A release is built by exactly one run: the push of its tag, or the dispatch
|
||||
# on its tag from the Create tag workflow. That run builds and signs the
|
||||
# binaries once, pushes the container images and creates a draft release with
|
||||
# the same executables, so the images and the release assets match. The draft
|
||||
# is published by hand; with immutable releases, its assets and tag are locked
|
||||
# from then on.
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
@@ -15,9 +22,6 @@ on:
|
||||
- "v*"
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
|
||||
permissions: {}
|
||||
|
||||
@@ -43,7 +47,7 @@ jobs:
|
||||
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
||||
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
||||
run: |
|
||||
# Pushes to main and the release branches, tags, releases and manual
|
||||
# Pushes to main, the release branches and tags, and manual
|
||||
# runs always test, so a gap in the filter below cannot let a
|
||||
# regression reach a branch that ships.
|
||||
if [[ "$EVENT_NAME" != "pull_request" || -z "$BASE_SHA" ]]; then
|
||||
@@ -85,6 +89,18 @@ jobs:
|
||||
persist-credentials: 'false'
|
||||
fetch-depth: '0'
|
||||
|
||||
# A published release is immutable. Rebuilding its tag would push images
|
||||
# whose executable differs from the release assets, so stop before that.
|
||||
- name: Check that the release is not published
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
if is_draft="$(gh release view "$GITHUB_REF_NAME" --json isDraft --jq .isDraft 2>/dev/null)" && [[ "$is_draft" == "false" ]]; then
|
||||
echo "::error::Release $GITHUB_REF_NAME is already published"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
|
||||
with:
|
||||
# renovate: golang=go
|
||||
@@ -142,6 +158,10 @@ jobs:
|
||||
# renovate: github=goreleaser/goreleaser
|
||||
version: v2.18.3
|
||||
args: build --clean
|
||||
env:
|
||||
# Several tags can point at one commit, such as an rc on the last
|
||||
# beta. Build the version of the tag this run is for.
|
||||
GORELEASER_CURRENT_TAG: ${{ github.ref_name }}
|
||||
|
||||
- name: Verify Go overlay
|
||||
run: go run ./tools/go-overlay verify dist/windows_exporter-amd64.exe dist/windows_exporter-arm64.exe
|
||||
@@ -150,7 +170,11 @@ jobs:
|
||||
run: |
|
||||
mkdir -p output
|
||||
|
||||
version="$(git describe --tags --always)"
|
||||
if [[ "$GITHUB_REF_TYPE" == "tag" ]]; then
|
||||
version="$GITHUB_REF_NAME"
|
||||
else
|
||||
version="$(git describe --tags --always)"
|
||||
fi
|
||||
version="${version#v}"
|
||||
version="${version//+/_}"
|
||||
printf '%s\n' "$version" | tee output/VERSION
|
||||
@@ -449,15 +473,14 @@ jobs:
|
||||
annotations: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
publish:
|
||||
# Publishing a release fires both a tag push and a release:published run for
|
||||
# the same tag. Upload only from the release run: it is the only one where
|
||||
# the release is guaranteed to exist, and uploading from both runs would
|
||||
# race on the same asset names.
|
||||
if: github.repository == 'prometheus-community/windows_exporter' && github.event_name == 'release'
|
||||
# Draft the release only once the images are pushed, so a published release
|
||||
# always has them.
|
||||
if: github.repository == 'prometheus-community/windows_exporter' && startsWith(github.ref, 'refs/tags/') && (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
|
||||
runs-on: ubuntu-26.04
|
||||
needs:
|
||||
- package
|
||||
- windows-test
|
||||
- docker
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
@@ -466,16 +489,33 @@ jobs:
|
||||
with:
|
||||
name: windows_exporter_binaries
|
||||
|
||||
- name: Publish Artifacts
|
||||
- name: Create draft release
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# The job runs without a checkout, so gh cannot infer the repository.
|
||||
GH_REPO: ${{ github.repository }}
|
||||
run: |
|
||||
gh release upload "$GITHUB_REF_NAME" \
|
||||
windows_exporter-*.exe \
|
||||
windows_exporter-*.msi \
|
||||
sha256sums.txt
|
||||
assets=(windows_exporter-*.exe windows_exporter-*.msi sha256sums.txt)
|
||||
|
||||
# A re-run replaces the assets of its own draft. A published release
|
||||
# is immutable and must not be touched.
|
||||
if is_draft="$(gh release view "$GITHUB_REF_NAME" --json isDraft --jq .isDraft 2>&1)"; then
|
||||
if [[ "$is_draft" != "true" ]]; then
|
||||
echo "::error::Release $GITHUB_REF_NAME is already published"
|
||||
exit 1
|
||||
fi
|
||||
gh release upload "$GITHUB_REF_NAME" --clobber "${assets[@]}"
|
||||
exit 0
|
||||
elif [[ "$is_draft" != *"release not found"* ]]; then
|
||||
echo "::error::Cannot look up release $GITHUB_REF_NAME: $is_draft"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
args=(--draft --verify-tag --generate-notes --title "$GITHUB_REF_NAME")
|
||||
if [[ "$GITHUB_REF_NAME" == *-* ]]; then
|
||||
args+=(--prerelease)
|
||||
fi
|
||||
gh release create "$GITHUB_REF_NAME" "${args[@]}" "${assets[@]}"
|
||||
|
||||
windows-test:
|
||||
name: Windows tests (${{ matrix.os }})
|
||||
@@ -1831,9 +1871,8 @@ jobs:
|
||||
|
||||
super-linter:
|
||||
name: Super Linter
|
||||
# Super Linter cannot derive the commit range VALIDATE_ALL_CODEBASE=false
|
||||
# needs from release events; the tag push run already lints the same commit.
|
||||
if: github.event_name != 'release'
|
||||
# The push run for the branch a tag is cut from already linted the commit.
|
||||
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
||||
runs-on: ubuntu-26.04
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -1884,6 +1923,7 @@ jobs:
|
||||
- build
|
||||
- package
|
||||
- docker
|
||||
- publish
|
||||
- windows-test
|
||||
- lint
|
||||
- super-linter
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
name: Create tag
|
||||
run-name: ${{ inputs.tag }}
|
||||
|
||||
# Creates a release tag on the commit the workflow runs on and starts CI for it.
|
||||
# A tag created with GITHUB_TOKEN does not trigger the tag push run, but a
|
||||
# workflow_dispatch does, so CI runs exactly once for the tag. That run builds
|
||||
# and signs the binaries, pushes the container images and creates the draft
|
||||
# release. Pushing a tag from a local clone triggers the same run directly.
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: Tag to create, such as v1.2.3 or v1.2.3-beta.1
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
create:
|
||||
name: Create tag
|
||||
if: github.repository == 'prometheus-community/windows_exporter'
|
||||
runs-on: ubuntu-26.04
|
||||
permissions:
|
||||
actions: write
|
||||
contents: write
|
||||
steps:
|
||||
- name: Create tag and start CI
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GH_REPO: ${{ github.repository }}
|
||||
TAG: ${{ inputs.tag }}
|
||||
run: |
|
||||
# The CI build derives the Windows file version from the tag and
|
||||
# accepts only these forms: alpha.N and beta.N up to 99, rc.N up to
|
||||
# 899.
|
||||
if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-(alpha|beta|rc)\.([0-9]+))?$ ]]; then
|
||||
echo "::error::Tag $TAG must look like v1.2.3, v1.2.3-beta.1 or v1.2.3-rc.1"
|
||||
exit 1
|
||||
fi
|
||||
number="${BASH_REMATCH[3]}"
|
||||
case "${BASH_REMATCH[2]}" in
|
||||
alpha|beta) limit=99 ;;
|
||||
rc) limit=899 ;;
|
||||
esac
|
||||
if [[ -n "$number" ]] && (( 10#$number > limit )); then
|
||||
echo "::error::Pre-release number of tag $TAG does not fit the file version scheme"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# A retry after a failed dispatch finds the tag already on this
|
||||
# commit and only starts CI again.
|
||||
if existing="$(gh api "repos/$GH_REPO/git/ref/tags/$TAG" --jq .object.sha 2>/dev/null)"; then
|
||||
if [[ "$existing" != "$GITHUB_SHA" ]]; then
|
||||
echo "::error::Tag $TAG already exists on $existing"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
gh api --method POST "repos/$GH_REPO/git/refs" \
|
||||
-f "ref=refs/tags/$TAG" \
|
||||
-f "sha=$GITHUB_SHA"
|
||||
fi
|
||||
|
||||
gh workflow run ci.yml --ref "$TAG"
|
||||
Reference in New Issue
Block a user