Skip to content

Commit 7f1fdae

Browse files
committed
Initial commit
1 parent f456c4f commit 7f1fdae

6 files changed

Lines changed: 426 additions & 219 deletions

File tree

‎.github/actions/spring-release-train-project-ready/action.yml‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,17 @@ runs:
199199
fi
200200
exit $watch_exit_code
201201
202+
# A hotfix release/<version> branch is registered in config/projects.json for its own
203+
# scheduled CI entry (create-hotfix-release-branch.yml); a GA release/<version> branch
204+
# never is. This runs for both — retire-branch-projects-json is a no-op (logs and
205+
# returns without committing) when the branch isn't registered in the first place.
206+
- name: Remove release branch from projects.json
207+
uses: ./.github/actions/retire-branch-projects-json
208+
with:
209+
repo: spring-cloud/${{ inputs.project }}
210+
branch: release/${{ steps.version.outputs.version }}
211+
token: ${{ inputs.token }}
212+
202213
- name: Remove release branch from Antora playbook
203214
uses: ./.github/actions/update-antora-playbook
204215
with:
Lines changed: 53 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,81 @@
11
# create-hotfix-branch
22

3-
Creates a commercial hotfix release branch directly from an OSS tag, applies all standard commercial branch initialisation steps, stamps the project version to a hotfix snapshot, ensures required release-train workflows are present, and (by default) triggers `release-train-join` in the commercial repo.
3+
Creates a commercial hotfix release branch. By default, the branch is cut from the tip of the commercial repo's `<major>.<minor>.x-internal` branch, preserving its full git history so the hotfix branch can later be rebased onto an updated `-internal` branch. Setting `use_tag` instead creates the branch from an OSS tag — an orphan branch with no shared history, the workflow's original behaviour. Either way, the workflow stamps the project version to a hotfix snapshot, ensures required release-train workflows are present, and (by default) triggers `release-train-join` in the commercial repo.
4+
5+
The hotfix version itself is never passed in directly — it's looked up from this project's own entry in the release train's `jenkins-releaser-config` properties file, keyed by `release_train_version`.
46

57
## What it does
68

7-
1. **Derives names** — strips the leading `v` from the tag, appends `.1`, and prefixes with `release/` to form the commercial branch name (e.g. `v5.0.1` → `release/5.0.1.1`). The commercial repo is always the OSS repo with `-commercial` appended.
8-
2. **Initialises the branch** — delegates to [`initialize-commercial-branch`](initialize-commercial-branch.yml), which runs the full suite of commercial setup actions: copy `.settings.xml`, update CI/PR workflows, update licence headers, replace OSS repositories with commercial Broadcom repositories, update distribution management, and update `config/projects.json`.
9-
3. **Creates a milestone** — creates a milestone in the commercial repo for the hotfix version if one does not already exist.
10-
4. **Stamps the project version** — updates the project version in `pom.xml`, `gradle.properties`, and `build.gradle` files to `<current-version>.1-SNAPSHOT` (e.g. `5.0.1` → `5.0.1.1-SNAPSHOT`). Optionally updates dependency versions at the same time.
11-
5. **Ensures required workflows** — checks that `release-train-join.yml` and `release-train-ready.yml` are present on the new branch. If either is missing, runs the workflow generator for that single branch to create them (see [Workflow generator SHA](#workflow-generator-sha)).
12-
6. **Triggers release-train-join** — dispatches `release-train-join.yml` in the commercial repo and waits for it to complete. This step is skipped when `spring_release_train` is left empty; the branch is still fully created and initialised.
13-
7. **Triggers CI** — squashes all `[skip actions]` initialisation commits into a single root commit and force pushes it (without `[skip actions]`) to start CI now that the branch is fully initialised.
9+
1. **Looks up the hotfix version and derives names** — detects this project's artifact ID from the OSS repo's root `pom.xml`, then reads `releaser.fixed-versions[<project>]` from the `release_train_version`'s properties file in `spring-cloud-release-commercial@jenkins-releaser-config` to get the hotfix version (e.g. `5.0.4.1`). From it: the commercial branch is `release/<version>` (e.g. `release/5.0.4.1`), the internal branch is `<major>.<minor>.x-internal` (e.g. `5.0.x-internal`), and (when `use_tag` is set) the OSS tag is `v<major>.<minor>.<patch>` (e.g. `v5.0.4`). The commercial repo is always the OSS repo with `-commercial` appended.
10+
2. **Validates the `-internal` branch** (default path only) — fails before making any changes if the `-internal` branch's `pom.xml` version doesn't exactly match `<major>.<minor>.<patch>-INTERNAL-SNAPSHOT` — i.e. if the `-internal` branch is out of date.
11+
3. **Creates the branch**:
12+
- Default (`use_tag: false`): forks `release/<version>` from the tip of the `-internal` branch via the GitHub API, preserving its full git history. Then adds a retargeted `ci-release.yml`/`release-ci-settings.xml` (via `add-commercial-release-files`, which already point the build at the commercial deploy target — no `.settings.xml` copy, workflow rewrite, or `pom.xml` distribution-management edit needed), updates license headers (and `checkstyle-header.txt`), and registers the branch in `config/projects.json` (a hotfix branch can fail its own CI independently of `-internal`, so it needs its own scheduled CI entry — this entry is removed automatically once the hotfix's release is finalized).
13+
- `use_tag: true`: delegates to [`initialize-commercial-branch`](initialize-commercial-branch.yml), which creates an orphan branch from the OSS tag and runs the full suite of commercial setup actions: copy `.settings.xml`, update CI/PR workflows, update licence headers, replace OSS repositories with commercial Broadcom repositories, update distribution management, and update `config/projects.json`.
14+
4. **Creates a milestone** — creates a milestone in the commercial repo for the hotfix version if one does not already exist.
15+
5. **Stamps the project version** — updates the project version in `pom.xml`, `gradle.properties`, and `build.gradle` files to `<version>-SNAPSHOT` (e.g. `5.0.4.1-SNAPSHOT`), and updates dependency versions from the release train. `versions` can supply additional dependency version overrides on top.
16+
6. **Ensures required workflows** — checks that `release-train-join.yml` and `release-train-ready.yml` are present on the new branch. If either is missing, runs the workflow generator for that single branch to create them (see [Workflow generator SHA](#workflow-generator-sha)).
17+
7. **Triggers release-train-join** — dispatches `release-train-join.yml` in the commercial repo and waits for it to complete. This step is skipped when `spring_release_train` is left empty; the branch is still fully created and initialised.
18+
8. **Triggers CI**:
19+
- Default path: squashes only the initialisation commits added on top of the `-internal` fork point into one commit and pushes it — history at and before the fork point is left untouched.
20+
- `use_tag` path: squashes all `[skip actions]` initialisation commits into a single orphan root commit and force pushes it (without `[skip actions]`) to start CI.
1421

1522
## Inputs
1623

1724
| Name | Required | Default | Description |
1825
|------|----------|---------|-------------|
1926
| `oss_repo` | yes | — | OSS repository name in the `spring-cloud` org (e.g. `spring-cloud-stream`) |
20-
| `oss_tag` | yes | — | Tag in the OSS repository to branch from (e.g. `v5.0.1`) |
27+
| `release_train_version` | yes | — | Release train version (e.g. `2025.1.2`) whose `jenkins-releaser-config` properties file names this project's hotfix version and supplies dependency versions |
28+
| `use_tag` | no | `false` | Create the branch from an OSS tag (`v<major>.<minor>.<patch>`) instead of the `<major>.<minor>.x-internal` branch |
2129
| `spring_release_train` | no | — | Spring release train this hotfix belongs to (e.g. `2026.1`). Passed to `release-train-join`, and supplying it is what triggers the join — leave it empty to prepare the branch without joining. |
22-
| `project_version` | no | `<current>.1-SNAPSHOT` | Override the auto-computed hotfix project version |
23-
| `release_train_version` | no | — | Release train version (e.g. `2025.1.2` or `2025.1.2.1-snapshot`). When supplied, all dependency version properties are updated from the Spring Cloud release train. Mutually exclusive with `versions`. |
24-
| `versions` | no | — | JSON map of dependency versions to apply directly (e.g. `{"spring-boot":"3.3.0","spring-cloud-commons":"4.1.1"}`). Mutually exclusive with `release_train_version`. |
30+
| `versions` | no | — | JSON map of dependency versions to apply on top of the release train's dependency versions (e.g. `{"spring-boot":"3.3.0","spring-cloud-commons":"4.1.1"}`) |
2531
| `sha` | no | Triggering commit | Commit SHA of this repo to copy release-train action files from when the workflow generator runs. See [Workflow generator SHA](#workflow-generator-sha). |
2632

2733
When called as a reusable workflow (`workflow_call`), a `token` secret can also be supplied; if omitted the `GH_ACTIONS_REPO_TOKEN` organisation secret is used.
2834

2935
## Branch and version naming
3036

31-
| OSS tag | Commercial repo | Commercial branch | Default project version |
32-
|---------|----------------|-------------------|------------------------|
33-
| `v5.0.1` | `org/repo-commercial` | `release/5.0.1.1` | `5.0.1.1-SNAPSHOT` |
34-
| `v3.3.2` | `org/repo-commercial` | `release/3.3.2.1` | `3.3.2.1-SNAPSHOT` |
35-
| `v2.0.0` | `org/repo-commercial` | `release/2.0.0.1` | `2.0.0.1-SNAPSHOT` |
36-
37-
## Version update behaviour
38-
39-
The version update step always runs. Exactly which versions are changed depends on the inputs supplied:
40-
41-
| Inputs | Project version | Dependency versions |
42-
|--------|----------------|---------------------|
43-
| Neither `versions` nor `release_train_version` | `<current>.1-SNAPSHOT` | unchanged |
44-
| `project_version` only | explicit override | unchanged |
45-
| `versions` only | `<current>.1-SNAPSHOT` | from `versions` map |
46-
| `versions` + `project_version` | explicit override | from `versions` map |
47-
| `release_train_version` | `<current>.1-SNAPSHOT` | fetched from Spring Cloud release train |
48-
| `release_train_version` + `project_version` | explicit override | fetched from Spring Cloud release train |
49-
50-
When `release_train_version` is used the action fetches the matching `jenkins-releaser-config` properties file from `spring-cloud-release-commercial`. The version can be specified as a GA version (`2025.1.2`), a full hotfix version (`2025.1.2.1`), or a SNAPSHOT version (`2025.1.2.1-snapshot`) — the correct parent GA properties file is always resolved automatically.
51-
52-
## Workflow generator SHA
53-
54-
When the `ensure-workflows` step needs to generate `release-train-join.yml` and `release-train-ready.yml` for a new branch, it invokes the [`generate-workflows-for-branch`](../actions/generate-workflows-for-branch/) action. That action copies release-train action files from this repo into the commercial repo. The `sha` input controls which commit of this repo is used as the source. When omitted, the commit that triggered the workflow is used.
55-
56-
This is useful if you need to ensure a specific version of the build/test action logic is deployed to the new branch:
37+
Given a release train whose `jenkins-releaser-config` properties file has `releaser.fixed-versions[<project>]=5.0.4.1`:
5738

58-
```bash
59-
gh workflow run create-hotfix-release-branch.yml \
60-
-f oss_repo=spring-cloud-foo \
61-
-f oss_tag=v5.0.1 \
62-
-f spring_release_train=2026.1 \
63-
-f sha=348109524f9790dc1e20d48043fb1ef4765373b8
64-
```
39+
| Derived value | Example |
40+
|---------------|---------|
41+
| Commercial repo | `org/repo-commercial` |
42+
| Commercial branch | `release/5.0.4.1` |
43+
| Internal branch (default path) | `5.0.x-internal` |
44+
| Expected internal `pom.xml` version (default path) | `5.0.4-INTERNAL-SNAPSHOT` |
45+
| OSS tag (`use_tag` path only) | `v5.0.4` |
46+
| Stamped project version | `5.0.4.1-SNAPSHOT` |
6547

6648
## Usage
6749

68-
### Manual dispatch (simplest — auto-computes everything)
50+
### Manual dispatch — default path, from `-internal`
6951

7052
```bash
7153
gh workflow run create-hotfix-release-branch.yml \
7254
-f oss_repo=spring-cloud-foo \
73-
-f oss_tag=v5.0.1 \
55+
-f release_train_version=2025.1.2 \
7456
-f spring_release_train=2026.1
7557
```
7658

77-
This creates `spring-cloud/spring-cloud-foo-commercial` branch `release/5.0.1.1`, stamps the project version to `5.0.1.1-SNAPSHOT`, and triggers `release-train-join`.
59+
This looks up `spring-cloud-foo`'s fixed version for release train `2025.1.2` (e.g. `5.0.4.1`), verifies `5.0.x-internal` in `spring-cloud/spring-cloud-foo-commercial` is at `5.0.4-INTERNAL-SNAPSHOT`, forks `release/5.0.4.1` from it, stamps the project version to `5.0.4.1-SNAPSHOT`, and triggers `release-train-join`.
7860

79-
### With an explicit project version
61+
### From an OSS tag instead of `-internal`
8062

8163
```bash
8264
gh workflow run create-hotfix-release-branch.yml \
8365
-f oss_repo=spring-cloud-foo \
84-
-f oss_tag=v5.0.1 \
66+
-f release_train_version=2025.1.2 \
8567
-f spring_release_train=2026.1 \
86-
-f project_version=5.0.1.2-SNAPSHOT
68+
-f use_tag=true
8769
```
8870

89-
### With dependency versions from a release train
90-
91-
```bash
92-
gh workflow run create-hotfix-release-branch.yml \
93-
-f oss_repo=spring-cloud-foo \
94-
-f oss_tag=v5.0.1 \
95-
-f spring_release_train=2026.1 \
96-
-f release_train_version=2025.1.2
97-
```
71+
Same version lookup, but creates the branch as an orphan copy of tag `v5.0.4`, with full commercial customisation, instead of forking `5.0.x-internal`.
9872

99-
### With explicit dependency versions (no release train lookup)
73+
### With explicit dependency version overrides
10074

10175
```bash
10276
gh workflow run create-hotfix-release-branch.yml \
10377
-f oss_repo=spring-cloud-foo \
104-
-f oss_tag=v5.0.1 \
78+
-f release_train_version=2025.1.2 \
10579
-f spring_release_train=2026.1 \
10680
-f versions='{"spring-boot":"3.3.5","spring-cloud-commons":"4.1.2"}'
10781
```
@@ -113,7 +87,7 @@ Create and initialise the branch but opt out of joining the release train:
11387
```bash
11488
gh workflow run create-hotfix-release-branch.yml \
11589
-f oss_repo=spring-cloud-foo \
116-
-f oss_tag=v5.0.1
90+
-f release_train_version=2025.1.2
11791
```
11892

11993
Omitting `spring_release_train` is what opts out: everything else runs, and the branch is
@@ -127,17 +101,31 @@ jobs:
127101
uses: spring-cloud/spring-cloud-github-actions/.github/workflows/create-hotfix-release-branch.yml@v1
128102
with:
129103
oss_repo: spring-cloud-foo
130-
oss_tag: v5.0.1
131-
spring_release_train: '2026.1'
132104
release_train_version: '2025.1.2'
105+
spring_release_train: '2026.1'
133106
secrets:
134107
token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
135108
```
136109
110+
## Workflow generator SHA
111+
112+
When the `ensure-workflows` step needs to generate `release-train-join.yml` and `release-train-ready.yml` for a new branch, it invokes the [`generate-workflows-for-branch`](../actions/generate-workflows-for-branch/) action. That action copies release-train action files from this repo into the commercial repo. The `sha` input controls which commit of this repo is used as the source. When omitted, the commit that triggered the workflow is used.
113+
114+
This is useful if you need to ensure a specific version of the build/test action logic is deployed to the new branch:
115+
116+
```bash
117+
gh workflow run create-hotfix-release-branch.yml \
118+
-f oss_repo=spring-cloud-foo \
119+
-f release_train_version=2025.1.2 \
120+
-f spring_release_train=2026.1 \
121+
-f sha=348109524f9790dc1e20d48043fb1ef4765373b8
122+
```
123+
137124
## Related workflows
138125

139126
| Workflow | Use when |
140127
|----------|----------|
128+
| [`create-oss-release-branch`](create-oss-release-branch.yml) | Cutting a GA (non-hotfix) `release/<version>` branch from `-internal` |
141129
| [`create-commercial-branch`](create-commercial-branch.yml) | Copying an OSS branch (not a tag) to the commercial repo |
142130
| [`initialize-commercial-branch`](initialize-commercial-branch.yml) | Full control over repo names, branch names, and all options |
143131
| [Run GitHub Actions Workflow Generator](run-github-actions-workflow-generator.README.md) | Regenerating workflows across all repos/branches in bulk |

‎.github/workflows/README-retire-branch.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,5 +135,5 @@ retired and frozen stays locked when the freeze is lifted.
135135
## Related workflows
136136

137137
- [`create-commercial-branch.yml`](README-create-commercial-branch.md) — creates a new commercial branch
138-
- [`create-hotfix-release-branch.yml`](README-create-hotfix-branch.md) — creates a hotfix branch from an OSS tag
138+
- [`create-hotfix-release-branch.yml`](README-create-hotfix-branch.md) — creates a hotfix branch, by default forked from the `-internal` branch
139139
- [`lock-unlock-branches.yml`](README-lock-branches.md) — temporarily freezes branches during a release, via a separate ruleset

0 commit comments

Comments
 (0)