mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-10-20 03:29: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
|
name: CI
|
||||||
|
|
||||||
# Pull requests run the Windows tests only when Go sources, modules, test data,
|
# Pull requests run the Windows tests only when Go sources, modules, test data,
|
||||||
# tools/, the configuration examples or this workflow change. Pushes, tags and
|
# tools/, the configuration examples or this workflow change. Pushes always run
|
||||||
# releases always run them.
|
# 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:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
@@ -15,9 +22,6 @@ on:
|
|||||||
- "v*"
|
- "v*"
|
||||||
pull_request:
|
pull_request:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
release:
|
|
||||||
types:
|
|
||||||
- published
|
|
||||||
|
|
||||||
permissions: {}
|
permissions: {}
|
||||||
|
|
||||||
@@ -43,7 +47,7 @@ jobs:
|
|||||||
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
||||||
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
||||||
run: |
|
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
|
# runs always test, so a gap in the filter below cannot let a
|
||||||
# regression reach a branch that ships.
|
# regression reach a branch that ships.
|
||||||
if [[ "$EVENT_NAME" != "pull_request" || -z "$BASE_SHA" ]]; then
|
if [[ "$EVENT_NAME" != "pull_request" || -z "$BASE_SHA" ]]; then
|
||||||
@@ -85,6 +89,18 @@ jobs:
|
|||||||
persist-credentials: 'false'
|
persist-credentials: 'false'
|
||||||
fetch-depth: '0'
|
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
|
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
|
||||||
with:
|
with:
|
||||||
# renovate: golang=go
|
# renovate: golang=go
|
||||||
@@ -142,6 +158,10 @@ jobs:
|
|||||||
# renovate: github=goreleaser/goreleaser
|
# renovate: github=goreleaser/goreleaser
|
||||||
version: v2.18.3
|
version: v2.18.3
|
||||||
args: build --clean
|
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
|
- name: Verify Go overlay
|
||||||
run: go run ./tools/go-overlay verify dist/windows_exporter-amd64.exe dist/windows_exporter-arm64.exe
|
run: go run ./tools/go-overlay verify dist/windows_exporter-amd64.exe dist/windows_exporter-arm64.exe
|
||||||
@@ -150,7 +170,11 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
mkdir -p output
|
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#v}"
|
||||||
version="${version//+/_}"
|
version="${version//+/_}"
|
||||||
printf '%s\n' "$version" | tee output/VERSION
|
printf '%s\n' "$version" | tee output/VERSION
|
||||||
@@ -449,15 +473,14 @@ jobs:
|
|||||||
annotations: ${{ steps.meta.outputs.labels }}
|
annotations: ${{ steps.meta.outputs.labels }}
|
||||||
|
|
||||||
publish:
|
publish:
|
||||||
# Publishing a release fires both a tag push and a release:published run for
|
# Draft the release only once the images are pushed, so a published release
|
||||||
# the same tag. Upload only from the release run: it is the only one where
|
# always has them.
|
||||||
# the release is guaranteed to exist, and uploading from both runs would
|
if: github.repository == 'prometheus-community/windows_exporter' && startsWith(github.ref, 'refs/tags/') && (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
|
||||||
# race on the same asset names.
|
|
||||||
if: github.repository == 'prometheus-community/windows_exporter' && github.event_name == 'release'
|
|
||||||
runs-on: ubuntu-26.04
|
runs-on: ubuntu-26.04
|
||||||
needs:
|
needs:
|
||||||
- package
|
- package
|
||||||
- windows-test
|
- windows-test
|
||||||
|
- docker
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
steps:
|
steps:
|
||||||
@@ -466,16 +489,33 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: windows_exporter_binaries
|
name: windows_exporter_binaries
|
||||||
|
|
||||||
- name: Publish Artifacts
|
- name: Create draft release
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
# The job runs without a checkout, so gh cannot infer the repository.
|
# The job runs without a checkout, so gh cannot infer the repository.
|
||||||
GH_REPO: ${{ github.repository }}
|
GH_REPO: ${{ github.repository }}
|
||||||
run: |
|
run: |
|
||||||
gh release upload "$GITHUB_REF_NAME" \
|
assets=(windows_exporter-*.exe windows_exporter-*.msi sha256sums.txt)
|
||||||
windows_exporter-*.exe \
|
|
||||||
windows_exporter-*.msi \
|
# A re-run replaces the assets of its own draft. A published release
|
||||||
sha256sums.txt
|
# 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:
|
windows-test:
|
||||||
name: Windows tests (${{ matrix.os }})
|
name: Windows tests (${{ matrix.os }})
|
||||||
@@ -1831,9 +1871,8 @@ jobs:
|
|||||||
|
|
||||||
super-linter:
|
super-linter:
|
||||||
name: Super Linter
|
name: Super Linter
|
||||||
# Super Linter cannot derive the commit range VALIDATE_ALL_CODEBASE=false
|
# The push run for the branch a tag is cut from already linted the commit.
|
||||||
# needs from release events; the tag push run already lints the same commit.
|
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
||||||
if: github.event_name != 'release'
|
|
||||||
runs-on: ubuntu-26.04
|
runs-on: ubuntu-26.04
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
@@ -1884,6 +1923,7 @@ jobs:
|
|||||||
- build
|
- build
|
||||||
- package
|
- package
|
||||||
- docker
|
- docker
|
||||||
|
- publish
|
||||||
- windows-test
|
- windows-test
|
||||||
- lint
|
- lint
|
||||||
- super-linter
|
- 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"
|
||||||
@@ -42,6 +42,15 @@ their runtime behavior.
|
|||||||
for `alpha.N`/`beta.N`, 100+N for `rc.N` and 1000 for the release, so MDM
|
for `alpha.N`/`beta.N`, 100+N for `rc.N` and 1000 for the release, so MDM
|
||||||
tools that compare file versions update from one beta to the next and to the
|
tools that compare file versions update from one beta to the next and to the
|
||||||
final release. Windows Installer itself ignores the fourth field.
|
final release. Windows Installer itself ignores the fourth field.
|
||||||
|
- A release is built once, by the CI run for its tag: a tag push, or the
|
||||||
|
dispatch that the Create tag workflow
|
||||||
|
([`tag.yml`](.github/workflows/tag.yml)) starts after creating the tag with
|
||||||
|
`GITHUB_TOKEN`, which cannot trigger the push run itself. That run pushes the
|
||||||
|
container images and creates a draft release with the same signed
|
||||||
|
executables; a maintainer publishes it. Releases are immutable once
|
||||||
|
published, so never upload assets after publishing, and never let a second
|
||||||
|
run build the same tag. Start releases only with that workflow or a tag push,
|
||||||
|
never by creating a release with a new tag in the GitHub UI.
|
||||||
|
|
||||||
New collectors need discussion with maintainers first. Prefer the configurable
|
New collectors need discussion with maintainers first. Prefer the configurable
|
||||||
`performancecounter` collector where it can provide the requested metrics, as
|
`performancecounter` collector where it can provide the requested metrics, as
|
||||||
|
|||||||
Reference in New Issue
Block a user