Skip to content

Commit fc94949

Browse files
docs: Document branch protection and release recovery workflow
Accept ASF branch protection policy in full (restrict_force_push + restrict_deletion). Document the toggle-and-restore procedure for release recovery when git push --force is needed, with emphasis on immediately restoring protection afterward. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 6a0fc29 commit fc94949

1 file changed

Lines changed: 59 additions & 1 deletion

File tree

src/site/markdown/release-process.md

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ If you have multiple keys, you can define a ~/.gnupg/gpg.conf file for a default
180180

181181
When asked for a tag name, accept the default value (in the following format: `vX.Y.Z`).
182182

183-
2. Perform the release using the following command - though be aware you cannot rollback as shown above after that. That may need to happen if there are site problems further below. To start over, use 'git reset --hard last-hash-before-release-started' , then 'git push --delete origin vX.Y.Z':
183+
2. Perform the release using the following command - though be aware you cannot rollback as shown above after that. That may need to happen if there are site problems further below. To start over, see the "Recovering from a failed release" section below.
184184

185185
mvn release:perform
186186

@@ -261,3 +261,61 @@ of Axis2, because not everybody subscribed to that list knows about the project.
261261
3. Remove old (archived) releases from <https://dist.apache.org/repos/dist/release/axis/axis2/java/core/>.
262262

263263
4. Create an empty release note for the next release under `src/site/markdown/release-notes`.
264+
265+
### Branch protection (`.asf.yaml`)
266+
267+
The repository has ASF-mandated branch protection rules in `.asf.yaml` that prevent
268+
force-push and branch deletion on `master` and `release/*` branches. This is a supply
269+
chain security measure applied across all ASF repositories (see PR #1200).
270+
271+
Under normal development, these rules are transparent — regular `git push` works as
272+
before. The protection only matters during release recovery (see below).
273+
274+
### Recovering from a failed release
275+
276+
If `mvn release:prepare` or `mvn release:perform` fails and you need to start over,
277+
the recovery requires `git push --force` which is blocked by branch protection.
278+
279+
**Recovery procedure:**
280+
281+
1. Temporarily disable force-push protection by editing `.asf.yaml` — remove or
282+
comment out `restrict_force_push: true`. Commit and push this change:
283+
284+
# Edit .asf.yaml to remove restrict_force_push: true
285+
git add .asf.yaml
286+
git commit -m "Temporarily disable force-push protection for release recovery"
287+
git push
288+
289+
Wait a minute for the GitHub ruleset to update.
290+
291+
2. Perform the recovery:
292+
293+
git reset --hard <last-commit-before-release-started>
294+
git push --force
295+
git push --delete origin vX.Y.Z
296+
297+
3. **Immediately restore protection** by reverting the `.asf.yaml` change:
298+
299+
git revert HEAD~1 # reverts the .asf.yaml disable commit
300+
git push
301+
302+
**Do not skip this step.** The risk of leaving force-push unprotected (credential
303+
compromise, accidental history rewrite) is higher than the inconvenience of the
304+
toggle. If the `.asf.yaml` change is accidentally included in a release commit,
305+
force-push protection will be silently disabled until someone notices.
306+
307+
4. Verify protection is restored: check the repository Settings → Rules → Rulesets
308+
page on GitHub to confirm force-push is blocked again.
309+
310+
**Why not just leave force-push enabled?** The ASF infrastructure team rolled out
311+
branch protection across all repositories after supply chain attacks (xz-utils, 2024)
312+
demonstrated the risk of history rewriting in open source projects. If a committer's
313+
credentials are compromised, force-push protection prevents an attacker from rewriting
314+
master to inject malicious code. The Axis2 project accepts this tradeoff: a small
315+
inconvenience during rare release failures in exchange for continuous protection
316+
against a real threat.
317+
318+
**Known issue:** The Maven site plugin has a bug with Git SCM URLs (MSITE-1033,
319+
status: IN PROGRESS) that can cause site deployment failures during the release
320+
process. This is a separate issue from branch protection but can compound the need
321+
for release restarts.

0 commit comments

Comments
 (0)