Skip to content

Prepare RC: push the RC tag only after staging succeeds - #3787

Merged
Fokko merged 1 commit into
apache:masterfrom
RussellSpitzer:fix/push-rc-tag-after-staging
Sep 11, 2026
Merged

Fokko merged 1 commit into
apache:masterfrom
RussellSpitzer:fix/push-rc-tag-after-staging

Conversation

@RussellSpitzer

Copy link
Copy Markdown
Member

Rationale for this change

In the release automation we pushed the tag before we were sure the staging artifacts were successfully pushed. This means we were burning an RC even if the stage failed.

What changes are included in this PR?

Tag is still created before staging, but not pushed until after staging.

Are these changes tested?

No

Are there any user-facing changes?

No

prepare-rc.sh created and pushed the RC tag at step 5, then did the work
that can actually fail -- Nexus deploy, source tarball, SVN staging -- in
steps 6-8. Every failure in that window left a published tag and consumed
an RC number; 1.19.0 accumulated eight orphaned tags (rc0-rc7, all on the
same commit) that way, and cancel-rc.sh cannot clean them up because it
requires a live staging repository.

Keep `git tag -a` at step 5 so local consumers still resolve it -- step 7
reads it via `git rev-list -1` and `git archive`, both local -- and move
only `git push origin <tag>` to step 9, immediately before the GitHub
pre-release that needs it on the remote. A failure in steps 6-8 now
leaves the tag only on the runner, so a retry reuses the same RC number
with no ref surgery.

The branch push stays at step 5: it publishes the version-bump commit, is
idempotent, and is what lets a retry skip the version update.

Trade-off: staged artifacts are briefly visible before the tag exists,
and a tag push failing after staging succeeds leaves a staged RC with no
tag. Recovery there is one idempotent `git push origin <tag>`, which is
cheaper than deleting a published ref.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

@Fokko Fokko left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, thanks @RussellSpitzer and thanks @wgtmac for the review 🚀

@Fokko
Fokko merged commit 21baba5 into apache:master Sep 11, 2026
6 checks passed
RussellSpitzer added a commit to RussellSpitzer/parquet-java that referenced this pull request Sep 22, 2026
The 2026-09-16 Cancel RC run for 1.19.0 rc9 failed with HTTP 401 because
release-cancel-rc.yml still read secrets.PARQUET_NEXUS_USER /
PARQUET_NEXUS_PASSWORD, which do not exist on apache/parquet-java. apache#3776
moved prepare-rc and publish to the ASF org-shared
NEXUS_STAGE_DEPLOYER_USER / NEXUS_STAGE_DEPLOYER_PW but missed cancel-rc,
the last two references in the tree. Nothing was cancelled: verification
is step 0, so the run aborted before dropping the staging repo or deleting
the SVN artifacts.

An absent secret expands to the empty string rather than failing, so the
credentials were present-but-blank and the first authenticated curl
reported only "error: 401". Add require_env and call it from all three
release scripts when DRY_RUN is not 1, so a missing credential is named
before any network call. Dry runs stay usable without secrets because
every authenticated call is already gated on DRY_RUN. _maven.sh had this
check for the deploy path only, which is why prepare-rc's Nexus 401 was
equally opaque.

Also apply apache#3787's tag-push ordering to publish-release.sh. It pushed the
final tag in step 3 and released the staging repo in step 4, so a Nexus
failure left a published release tag and the "Final release tag already
exists" guard then blocked the retry -- the same trap apache#3787 removed from
prepare-rc, where eight orphaned 1.19.0 RC tags accumulated. Keep git tag
-a in step 3 for the local reads that follow and move only the push to
step 5, immediately before the GitHub release that needs it on the remote.

Generated-by: Claude Opus 5 (1M context)
Fokko pushed a commit that referenced this pull request Sep 23, 2026
…3814)

The 2026-09-16 Cancel RC run for 1.19.0 rc9 failed with HTTP 401 because
release-cancel-rc.yml still read secrets.PARQUET_NEXUS_USER /
PARQUET_NEXUS_PASSWORD, which do not exist on apache/parquet-java. #3776
moved prepare-rc and publish to the ASF org-shared
NEXUS_STAGE_DEPLOYER_USER / NEXUS_STAGE_DEPLOYER_PW but missed cancel-rc,
the last two references in the tree. Nothing was cancelled: verification
is step 0, so the run aborted before dropping the staging repo or deleting
the SVN artifacts.

An absent secret expands to the empty string rather than failing, so the
credentials were present-but-blank and the first authenticated curl
reported only "error: 401". Add require_env and call it from all three
release scripts when DRY_RUN is not 1, so a missing credential is named
before any network call. Dry runs stay usable without secrets because
every authenticated call is already gated on DRY_RUN. _maven.sh had this
check for the deploy path only, which is why prepare-rc's Nexus 401 was
equally opaque.

Also apply #3787's tag-push ordering to publish-release.sh. It pushed the
final tag in step 3 and released the staging repo in step 4, so a Nexus
failure left a published release tag and the "Final release tag already
exists" guard then blocked the retry -- the same trap #3787 removed from
prepare-rc, where eight orphaned 1.19.0 RC tags accumulated. Keep git tag
-a in step 3 for the local reads that follow and move only the push to
step 5, immediately before the GitHub release that needs it on the remote.

Generated-by: Claude Opus 5 (1M context)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants