-
Notifications
You must be signed in to change notification settings - Fork 0
151 lines (138 loc) · 5.54 KB
/
Copy pathrelease.yml
File metadata and controls
151 lines (138 loc) · 5.54 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
141
142
143
144
145
146
147
148
149
150
151
name: Release
# Publishes to NuGet either:
# - manually (Actions > Release > Run workflow), choosing the semver part to bump, or
# - automatically when a PR is merged to main carrying a release:major|minor|patch label.
#
# The version is computed by bumping the latest v* git tag (falling back to the csproj
# <Version> when no tag exists yet), so <Version> never has to be edited by hand. Each
# successful publish creates the matching v<version> tag and a GitHub Release.
#
# Publishing uses NuGet trusted publishing (OIDC) — no long-lived API key. The job
# requests a short-lived key at runtime via the NuGet/login action, so it needs
# `id-token: write` permission and a repository secret NUGET_USER holding the
# nuget.org username (profile name, NOT an email).
#
# Trusted publishing setup (one-time, on nuget.org > your account > Trusted Publishing):
# Repository Owner: Mako88 Repository: SimpleHttpClient
# Workflow File: release.yml Environment: (leave empty)
# Docs: https://learn.microsoft.com/en-us/nuget/nuget-org/trusted-publishing
#
# First-time setup: seed a tag matching the last published version so the first bump is
# correct, e.g. git tag v4.1.0 && git push origin v4.1.0
on:
workflow_dispatch:
inputs:
bump:
description: 'Semver part to bump'
required: true
default: patch
type: choice
options: [patch, minor, major]
pull_request:
types: [closed]
branches: [main]
concurrency:
group: release
cancel-in-progress: false
permissions:
contents: write
id-token: write # request the OIDC token used for NuGet trusted publishing
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
8.0.x
10.0.x
# Decide whether to publish and which part to bump.
- name: Determine bump
id: bump
env:
EVENT: ${{ github.event_name }}
INPUT_BUMP: ${{ github.event.inputs.bump }}
MERGED: ${{ github.event.pull_request.merged }}
LABELS: ${{ toJSON(github.event.pull_request.labels.*.name) }}
shell: bash
run: |
set -euo pipefail
if [ "$EVENT" = "workflow_dispatch" ]; then
echo "bump=$INPUT_BUMP" >> "$GITHUB_OUTPUT"
echo "proceed=true" >> "$GITHUB_OUTPUT"
exit 0
fi
# pull_request closed: only on a real merge carrying a release label
if [ "$MERGED" != "true" ]; then
echo "Not a merge; skipping."
echo "proceed=false" >> "$GITHUB_OUTPUT"
exit 0
fi
bump=""
for l in $(echo "$LABELS" | python3 -c "import sys,json; print(' '.join(json.load(sys.stdin)))"); do
case "$l" in
release:major) bump=major ;;
release:minor) bump=minor ;;
release:patch) bump=patch ;;
esac
done
if [ -z "$bump" ]; then
echo "No release:* label on the merged PR; skipping publish."
echo "proceed=false" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "bump=$bump" >> "$GITHUB_OUTPUT"
echo "proceed=true" >> "$GITHUB_OUTPUT"
- name: Compute version
if: steps.bump.outputs.proceed == 'true'
id: version
shell: bash
run: |
set -euo pipefail
latest="$(git tag --list 'v*' --sort=-v:refname | head -n1)"
if [ -z "$latest" ]; then
base="$(grep -oPm1 '(?<=<Version>)[^<]+' src/SimpleHttpClient/SimpleHttpClient.csproj)"
else
base="${latest#v}"
fi
IFS='.' read -r MA MI PA <<< "$base"
case "${{ steps.bump.outputs.bump }}" in
major) MA=$((MA+1)); MI=0; PA=0 ;;
minor) MI=$((MI+1)); PA=0 ;;
patch) PA=$((PA+1)) ;;
esac
newver="$MA.$MI.$PA"
echo "version=$newver" >> "$GITHUB_OUTPUT"
echo "Releasing $newver (base $base, bump ${{ steps.bump.outputs.bump }})"
- name: Test
if: steps.bump.outputs.proceed == 'true'
run: dotnet test src/SimpleHttpClient.Tests.Integration/SimpleHttpClient.Tests.csproj -c Release -f net10.0
# GeneratePackageOnBuild is enabled, so a Release build emits the .nupkg.
- name: Build package
if: steps.bump.outputs.proceed == 'true'
run: dotnet build src/SimpleHttpClient/SimpleHttpClient.csproj -c Release -p:Version=${{ steps.version.outputs.version }}
# Exchange the GitHub OIDC token for a short-lived nuget.org API key (valid ~1h).
# Done right before push so it doesn't expire mid-build.
- name: NuGet login (OIDC -> short-lived API key)
if: steps.bump.outputs.proceed == 'true'
uses: NuGet/login@v1
id: nuget-login
with:
user: ${{ secrets.NUGET_USER }}
- name: Push to NuGet
if: steps.bump.outputs.proceed == 'true'
run: dotnet nuget push "src/SimpleHttpClient/bin/Release/*.nupkg" --api-key ${{ steps.nuget-login.outputs.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
- name: Tag and create GitHub Release
if: steps.bump.outputs.proceed == 'true'
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
tag="v${{ steps.version.outputs.version }}"
git tag "$tag"
git push origin "$tag"
gh release create "$tag" --title "$tag" --generate-notes