-
Notifications
You must be signed in to change notification settings - Fork 1
140 lines (130 loc) · 6 KB
/
Copy pathbuild-release-task.yml
File metadata and controls
140 lines (130 loc) · 6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
name: Build project release task
on:
workflow_call:
inputs:
# Input to control whether to create a GitHub release
github:
required: false
type: boolean
default: false
# Input to control whether to push the library to NuGet.org
nuget:
required: false
type: boolean
default: false
# Git ref to check out / version (empty = default checkout ref).
ref:
required: false
type: string
default: ''
# Logical branch driving config / tags / prerelease for every target.
# Required (no `github.ref_name` fallback): the publisher builds both
# `main` and `develop` from one run whose `github.ref_name` is `main`,
# so a silent fallback would mislabel the develop leg. Every caller
# passes it explicitly; a missing value should fail loudly.
branch:
required: true
type: string
# Smoke mode: reduced, never-published build for fast PR feedback.
# Forwarded to every target; also hard-disables every push below so a
# smoke run can never publish regardless of the publish flags.
smoke:
required: false
type: boolean
default: false
# Per-target presence gate. Default true (build everything). A PR smoke
# run sets this from the paths-filter so the library only builds when it
# actually changed.
enable_nuget:
required: false
type: boolean
default: true
jobs:
get-version:
name: Get version information job
uses: ./.github/workflows/get-version-task.yml
secrets: inherit
with:
ref: ${{ inputs.ref }}
build-nugetlibrary:
name: Build NuGet library job
if: ${{ inputs.enable_nuget }}
needs: [get-version]
uses: ./.github/workflows/build-nugetlibrary-task.yml
secrets: inherit
with:
# Pin to the exact commit get-version resolved (immutable), not the
# possibly-moving branch ref: the publisher passes a branch name, and a
# commit landing mid-run could otherwise build artifacts from a different
# commit than the one the release tag (also GitCommitId) points at.
ref: ${{ needs.get-version.outputs.GitCommitId }}
branch: ${{ inputs.branch }}
# Conditional push to NuGet.org — never on a smoke build.
push: ${{ inputs.nuget && !inputs.smoke }}
github-release:
name: Publish GitHub release job
# `&& !inputs.smoke` enforces the "smoke never publishes" guarantee at the
# job level too (matching the `&& !inputs.smoke` push gate above), so a
# smoke caller that also set `github: true` still can't create a release.
if: ${{ inputs.github && !inputs.smoke }}
runs-on: ubuntu-latest
needs: [get-version, build-nugetlibrary]
steps:
# Check out the exact built commit (NBGV `GitCommitId`), not the
# possibly-moving `inputs.ref` branch, so the uploaded release files
# match the tag even if the branch advances mid-run.
- name: Checkout code step
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ needs.get-version.outputs.GitCommitId }}
- name: Download library build artifacts step
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
artifact-ids: ${{ needs.build-nugetlibrary.outputs.artifact-id }}
path: ./Publish
# The weekly publisher re-runs even when a branch has no new commits, so
# NBGV can produce a SemVer2 that was already released. GitHub release
# creation has no built-in skip-duplicate (unlike NuGet's
# `--skip-duplicate`), and re-publishing an unchanged version is exactly
# the churn the two-phase model avoids — so skip the release step when a
# release for this tag already exists.
- name: Check for existing release step
id: release-exists
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ needs.get-version.outputs.SemVer2 }}
run: |
set -euo pipefail
if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
echo "exists=true" >> "$GITHUB_OUTPUT"
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo "Release $TAG already exists; workflow_dispatch will refresh it."
else
echo "Release $TAG already exists; skipping release creation (no-op republish)."
fi
else
echo "exists=false" >> "$GITHUB_OUTPUT"
fi
# `target_commitish` MUST be set explicitly: softprops doesn't pass a
# default through, and GitHub's REST API then defaults the new tag to
# the repository's default branch (main). We pin it to NBGV's
# `GitCommitId` — the exact commit the version was computed from. This
# avoids two bugs: `github.sha` would be wrong (the publisher's branch
# matrix builds `develop` from a run whose `github.sha` is main's tip),
# and `inputs.branch` would be a moving ref (a commit landing mid-run
# could tag the release on a newer commit than the one that was built).
# Skip the no-op weekly republish when the tag already exists, but always
# allow a manual `workflow_dispatch` through so it can repair/refresh a
# partially-created release for the same tag.
- name: Create GitHub release step
if: ${{ steps.release-exists.outputs.exists == 'false' || github.event_name == 'workflow_dispatch' }}
uses: softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3.0.1
with:
generate_release_notes: true
tag_name: ${{ needs.get-version.outputs.SemVer2 }}
target_commitish: ${{ needs.get-version.outputs.GitCommitId }}
prerelease: ${{ inputs.branch != 'main' }}
files: |
LICENSE
README.md
./Publish/*