Skip to content

Commit bc6375d

Browse files
committed
Support updating -internal branches in update versions workflow
1 parent bd65067 commit bc6375d

4 files changed

Lines changed: 48 additions & 11 deletions

File tree

‎.github/actions/resolve-release-branch/README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ same project is refused rather than silently rewriting `main`.
2929
| Input | Description | Required | Default |
3030
|-------|-------------|----------|---------|
3131
| `repo` | Full repository path (e.g. `spring-cloud/spring-cloud-config`) | Yes | |
32+
| `internal` | Resolve `<major>.<minor>.x-internal` instead of `<major>.<minor>.x`. No `main` fallback; a missing branch is `branch-not-found`. | No | `false` |
3233
| `version` | The version whose line is wanted. Any qualifier is stripped first, so `5.0.4-SNAPSHOT`, `5.1.0-INTERNAL-SNAPSHOT`, `5.1.0-M1` and `5.0.3` all resolve the same way. | Yes | |
3334
| `commercial` | Repository is a commercial one, so there is no `main` to fall back to | No | `false` |
3435
| `token` | Token with read access to the repository | Yes | |

‎.github/actions/resolve-release-branch/action.yml‎

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
name: 'Resolve Release Branch'
22
description: >
33
Resolves the maintenance branch a given project version belongs to: <major>.<minor>.x
4-
when it exists, otherwise main for OSS repositories whose main is on that same line.
4+
when it exists, otherwise main for OSS repositories whose main is on that same line. With
5+
internal=true it resolves <major>.<minor>.x-internal instead, with no fallback.
56
67
inputs:
78
repo:
@@ -20,6 +21,13 @@ inputs:
2021
reported rather than guessed at.
2122
required: false
2223
default: 'false'
24+
internal:
25+
description: >
26+
When true, resolve the long-lived <major>.<minor>.x-internal branch of a commercial
27+
repository rather than <major>.<minor>.x. A missing branch is reported, never replaced
28+
by main.
29+
required: false
30+
default: 'false'
2331
token:
2432
description: 'GitHub token with read access to the repository'
2533
required: true
@@ -48,6 +56,7 @@ runs:
4856
REPO: ${{ inputs.repo }}
4957
VERSION: ${{ inputs.version }}
5058
COMMERCIAL: ${{ inputs.commercial }}
59+
INTERNAL: ${{ inputs.internal }}
5160
run: |
5261
node - << 'JSEOF'
5362
const fs = require('fs');
@@ -56,6 +65,7 @@ runs:
5665
const repo = process.env.REPO;
5766
const version = process.env.VERSION;
5867
const commercial = process.env.COMMERCIAL === 'true';
68+
const internal = process.env.INTERNAL === 'true';
5969
6070
const out = process.env.GITHUB_OUTPUT;
6171
const emit = (k, v) => fs.appendFileSync(out, `${k}=${v}\n`);
@@ -78,7 +88,8 @@ runs:
7888
stop('version-mismatch',
7989
`ERROR: '${version}' is not a numeric version, so no branch can be derived from it.`);
8090
}
81-
const target = parts.slice(0, -1).join('.') + '.x';
91+
const line = parts.slice(0, -1).join('.') + '.x';
92+
const target = internal ? `${line}-internal` : line;
8293
8394
const branchExists = branch => {
8495
try {
@@ -96,6 +107,12 @@ runs:
96107
process.exit(0);
97108
}
98109
110+
// An -internal branch is a copy of the OSS branch kept for the commercial repos; main is
111+
// never a stand-in for it.
112+
if (internal) {
113+
stop('branch-not-found', `ERROR: ${repo} has no ${target} branch. Skipping this project.`);
114+
}
115+
99116
// Commercial repos have no main branch at all - spring-cloud-config-commercial's
100117
// default is 4.3.x - so there is no sane fallback to make.
101118
if (commercial) {

‎.github/workflows/README-update-versions.md‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,11 @@ If that branch does not exist:
5454
- **commercial** — the project is skipped. Commercial repos have no `main` to fall back to (`spring-cloud-config-commercial`'s default branch is `4.3.x`).
5555
- **OSS** — falls back to `main`, but only after reading `pom.xml` on `main` and confirming it is on the same `major.minor` line. Otherwise the project is skipped with `version-mismatch` rather than bumping an unrelated major to these versions.
5656

57-
**There is no input to override this.** Between those two rules every branch the workflow targets is covered: the only names in [`projects.json`](../../config/projects.json) that are not `<major>.<minor>.x` are `main`, which the fallback handles, and the `-internal` branches, which this never targets — those are rebased from the OSS branches it does update. An override input would therefore have no correct use, and would be the one way to push a train's versions onto a branch they do not belong on, since a branch given by hand cannot be checked against the version the way a derived one can.
57+
### `-INTERNAL-SNAPSHOT` trains
58+
59+
A `release_train_version` such as `2025.1.4-INTERNAL-SNAPSHOT` targets the long-lived `<major>.<minor>.x-internal` branches of the **commercial** repositories instead (`5.1.0-INTERNAL-SNAPSHOT` → `5.1.x-internal`). There is no fallback: a project without that branch is skipped as `branch-not-found`. The run fails early if `commercial` is not set (or the project names lack `-commercial`), since OSS repos have no `-internal` branches. The properties file read is `2025_1_4-internal-snapshot.properties` on `jenkins-releaser-config`, which must already exist.
60+
61+
**There is no input to override this.** Between those two rules every branch the workflow targets is covered: the only names in [`projects.json`](../../config/projects.json) that are not `<major>.<minor>.x` are `main`, which the fallback handles, and the `-internal` branches, which are reached only through an `-INTERNAL` train (above). An override input would therefore have no correct use, and would be the one way to push a train's versions onto a branch they do not belong on, since a branch given by hand cannot be checked against the version the way a derived one can.
5862

5963
## The raw wait
6064

‎.github/workflows/update-versions.yml‎

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ on:
3232
workflow_dispatch:
3333
inputs:
3434
release_train_version:
35-
description: 'Release train version whose versions should be applied (e.g. 2025.1.3-SNAPSHOT, or 2025.1.2). Must have a matching properties file on the jenkins-releaser-config branch.'
35+
description: 'Release train version whose versions should be applied (e.g. 2025.1.3-SNAPSHOT, 2025.1.2, or 2025.1.4-INTERNAL-SNAPSHOT for the -internal branches of the commercial repos). Must have a matching properties file on the jenkins-releaser-config branch.'
3636
required: true
3737
type: string
3838
commercial:
@@ -69,6 +69,7 @@ jobs:
6969
commercial: ${{ steps.parse.outputs.commercial }}
7070
release-repo: ${{ steps.parse.outputs.release-repo }}
7171
props-file: ${{ steps.parse.outputs.props-file }}
72+
internal: ${{ steps.parse.outputs.internal }}
7273
steps:
7374
# Only so the inline scripts below can require .github/scripts/.
7475
- uses: actions/checkout@v4
@@ -103,13 +104,19 @@ jobs:
103104
const fail = (...msg) => { for (const m of msg) console.error(m); process.exit(1); };
104105
105106
// 3 or 4 numeric segments, optionally with a qualifier: 2025.1.3, 2025.1.3-SNAPSHOT,
106-
// 2025.1.0-RC1, 2025.1.2.1. Anything else would resolve to a properties file name
107-
// that cannot exist, so it is rejected here rather than as a confusing 404.
108-
if (!/^\d+(\.\d+){2,3}(-[A-Za-z][\w.]*)?$/.test(trainVersion)) {
107+
// 2025.1.0-RC1, 2025.1.2.1, 2025.1.4-INTERNAL-SNAPSHOT (the qualifier may itself
108+
// contain hyphens). Anything else would resolve to a properties file name that cannot
109+
// exist, so it is rejected here rather than as a confusing 404.
110+
if (!/^\d+(\.\d+){2,3}(-[A-Za-z][\w.]*)*$/.test(trainVersion)) {
109111
fail(`ERROR: release_train_version must be 3 or 4 numeric segments with an optional ` +
110-
`qualifier (e.g. 2025.1.3-SNAPSHOT or 2025.1.2); got '${trainVersion}'.`);
112+
`qualifier (e.g. 2025.1.3-SNAPSHOT, 2025.1.2 or 2025.1.4-INTERNAL-SNAPSHOT); ` +
113+
`got '${trainVersion}'.`);
111114
}
112115
116+
// An -INTERNAL train addresses the <major>.<minor>.x-internal branches, which exist
117+
// only in the commercial repositories.
118+
const internal = /-INTERNAL(-|$)/i.test(trainVersion);
119+
113120
// This job must read exactly the file update-project-versions will read, or it
114121
// would validate one file and apply another.
115122
const propsFile = releaserConfigFileName(trainVersion);
@@ -140,6 +147,11 @@ jobs:
140147
}
141148
}
142149
150+
if (internal && !commercial) {
151+
fail(`ERROR: ${trainVersion} is an -INTERNAL train, and -internal branches exist only ` +
152+
'in the -commercial repositories. Set commercial, or use -commercial project names.');
153+
}
154+
143155
// Where the config lives, from the shared module - it owns that choice for every
144156
// caller. `commercial` decides only which project repositories are updated.
145157
const releaseRepo = RELEASER_CONFIG_REPO;
@@ -231,6 +243,7 @@ jobs:
231243
232244
console.log('');
233245
console.log(`commercial: ${commercial}`);
246+
console.log(`internal: ${internal}`);
234247
console.log(`release repo: ${releaseRepo}`);
235248
console.log(`properties file: ${propsFile}`);
236249
console.log('');
@@ -243,6 +256,7 @@ jobs:
243256
fs.appendFileSync(out, `commercial=${commercial}\n`);
244257
fs.appendFileSync(out, `release-repo=${releaseRepo}\n`);
245258
fs.appendFileSync(out, `props-file=${propsFile}\n`);
259+
fs.appendFileSync(out, `internal=${internal}\n`);
246260
JSEOF
247261
248262
update:
@@ -265,16 +279,17 @@ jobs:
265279
# ── resolve the branch to work on ────────────────────────────────────────────────
266280
# The branch is always derived from the version in the properties file - there is no
267281
# input to override it. Between the .x derivation and the main fallback the action
268-
# makes, every branch this workflow targets is covered: the only names in projects.json
269-
# that are not <major>.<minor>.x are main, and the -internal branches, which are rebased
270-
# from the OSS branches this updates and so are never targeted here.
282+
# makes, every OSS and commercial release-line branch this workflow targets is covered.
283+
# An -INTERNAL train is the exception: it resolves to <major>.<minor>.x-internal, with
284+
# no fallback, and only in the commercial repos.
271285
- name: Resolve target branch
272286
id: branch
273287
uses: ./.github/actions/resolve-release-branch
274288
with:
275289
repo: ${{ matrix.repo }}
276290
version: ${{ matrix.version }}
277291
commercial: ${{ needs.setup.outputs.commercial }}
292+
internal: ${{ needs.setup.outputs.internal }}
278293
token: ${{ inputs.token || secrets.GH_ACTIONS_REPO_TOKEN }}
279294

280295
- name: Clone project

0 commit comments

Comments
 (0)