-
Notifications
You must be signed in to change notification settings - Fork 25
150 lines (132 loc) · 5.48 KB
/
cd.yml
File metadata and controls
150 lines (132 loc) · 5.48 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
name: CD
on:
workflow_dispatch:
push:
branches: [develop, main]
# Pre-release on develop is interruptible (newer commit supersedes the older
# build); a stable release on main must never be cancelled mid-run, hence the
# ref-conditional cancel-in-progress.
concurrency:
group: cd-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
permissions:
contents: write
pull-requests: write
jobs:
# ═══════════════════════════════════════════════
# DEVELOP PATH: Pre-release
# ═══════════════════════════════════════════════
pre-release:
if: >-
github.ref == 'refs/heads/develop'
|| (github.event_name == 'workflow_dispatch' && github.ref != 'refs/heads/main')
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.tag.outputs.tag }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Compute next version from conventional commits
id: tag
run: |
# Latest stable tag follows the release-please format: icm-v0.10.42.
# The `^icm-v…$` anchor filters out any pre-release suffix
# (e.g. icm-v0.10.42-rc.1) without filtering on a bare dash —
# the icm- prefix itself contains one, which broke the original
# `grep -v '-'` borrowed from rtk-ai/rtk where tags are bare `vX.Y.Z`.
LATEST_TAG=$(git tag -l 'icm-v[0-9]*.[0-9]*.[0-9]*' --sort=-version:refname \
| grep -E '^icm-v[0-9]+\.[0-9]+\.[0-9]+$' | head -1)
if [ -z "$LATEST_TAG" ]; then
echo "::error::No stable icm-v* release tag found"
exit 1
fi
LATEST_VERSION="${LATEST_TAG#icm-v}"
echo "Latest stable: $LATEST_TAG"
COMMITS=$(git log "${LATEST_TAG}..HEAD" --format="%s")
HAS_BREAKING=$(echo "$COMMITS" | grep -cE '^[a-z]+(\(.+\))?!:' || true)
HAS_FEAT=$(echo "$COMMITS" | grep -cE '^feat(\(.+\))?:' || true)
HAS_FIX=$(echo "$COMMITS" | grep -cE '^fix(\(.+\))?:' || true)
echo "Commits since $LATEST_TAG: breaking=$HAS_BREAKING feat=$HAS_FEAT fix=$HAS_FIX"
# release-please-config.json sets bump-minor-pre-major +
# bump-patch-for-minor-pre-major, so for major=0:
# breaking -> minor bump
# feat -> patch bump
# fix -> patch bump
IFS='.' read -r MAJOR MINOR PATCH <<< "$LATEST_VERSION"
if [ "$MAJOR" -eq 0 ]; then
if [ "$HAS_BREAKING" -gt 0 ]; then
MINOR=$((MINOR + 1)); PATCH=0
elif [ "$HAS_FEAT" -gt 0 ] || [ "$HAS_FIX" -gt 0 ]; then
PATCH=$((PATCH + 1))
else
PATCH=$((PATCH + 1))
fi
else
if [ "$HAS_BREAKING" -gt 0 ]; then
MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0
elif [ "$HAS_FEAT" -gt 0 ]; then
MINOR=$((MINOR + 1)); PATCH=0
else
PATCH=$((PATCH + 1))
fi
fi
VERSION="${MAJOR}.${MINOR}.${PATCH}"
TAG="icm-dev-v${VERSION}-rc.${{ github.run_number }}"
echo "Next version: $VERSION (from $LATEST_VERSION)"
echo "Pre-release tag: $TAG"
if git ls-remote --tags origin "refs/tags/${TAG}" | grep -q .; then
echo "::error::Tag ${TAG} already exists"
exit 1
fi
echo "tag=$TAG" >> $GITHUB_OUTPUT
build-prerelease:
name: Build pre-release
needs: pre-release
if: needs.pre-release.outputs.tag != ''
uses: ./.github/workflows/release.yml
with:
tag: ${{ needs.pre-release.outputs.tag }}
prerelease: true
permissions:
contents: write
secrets: inherit
# ═══════════════════════════════════════════════
# MAIN PATH: Stable release via release-please
# ═══════════════════════════════════════════════
release-please:
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
runs-on: ubuntu-latest
outputs:
release_created: ${{ steps.release.outputs.releases_created }}
tag_name: ${{ steps.release.outputs['crates/icm-cli--tag_name'] }}
steps:
- uses: googleapis/release-please-action@v4
id: release
build-release:
name: Build and upload release assets
needs: release-please
if: ${{ needs.release-please.outputs.release_created == 'true' }}
uses: ./.github/workflows/release.yml
with:
tag: ${{ needs.release-please.outputs.tag_name }}
prerelease: false
permissions:
contents: write
secrets: inherit
update-latest-tag:
name: Update 'latest' tag
needs: [release-please, build-release]
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Update latest tag
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -fa latest -m "Latest stable release (${{ needs.release-please.outputs.tag_name }})"
git push origin latest --force