Skip to content

Enhance the release process - #909

Merged
LikeTheSalad merged 6 commits into
mainfrom
feature/android-release-automation
Sep 23, 2026
Merged

LikeTheSalad merged 6 commits into
mainfrom
feature/android-release-automation

Conversation

@LikeTheSalad

@LikeTheSalad LikeTheSalad commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Previously, the release process required some manual steps that could be further automated, such as manually forming a set of release notes and passing them to the release preparation action, and also running the release workflow manually and ensuring that the correct release branch was selected. Now, a "prepare release" action dispatch opens a preparation pull request into a releasing/x.y.z branch, with an additional/optional path of using an AI skill to help with writing the release notes and also helping with other arguments needed to prepare the release. Once the generated PR gets merged, the actual release is executed automatically rather than having to manually continue with the process of finding the right next GH action and running it by choosing the right branch. The automation then opens a second pull request into main with the release changes and the next development version. Nothing is merged by automation.

What this helps with:

  • The process makes the overall release less error-prone, as the version for releasing isn't chosen manually in any step, and it's also verified based on the latest released tag available to avoid accidental version skips.
  • Buildkite builds exactly the selected commit and refuses anything else.
  • A failed run is rerun in place, and a half-published release can continue where it left off.
  • The outcome reaches Slack with links to the GitHub Release and the follow-up pull request, or to the failed run.
  • Fewer moving parts to maintain: commented shell scripts replace the Kotlin renderer and the one-off scripts.
  • An optional AI skill can help draft the initial release preparation PR. The skill won't do anything that cannot be done manually already; it just makes the process smoother.

Changes

  • Rewrite prepare-release.yml and its script: derive the version, render the release notes at the existing marker, regenerate the NOTICE files, push releasing/x.y.z and prepare/x.y.z, and open the preparation pull request.
  • Add publish-release.yml with a guard and a finalize script: on merge into releasing/x.y.z, build and publish once in Buildkite from the merged commit, attest the artifacts, tag, create the GitHub Release, commit the next -SNAPSHOT version, and open the release pull request into main.
  • Rewrite .ci/release.sh to build only the merged commit, verify credentials before any upload, publish per target, and check the registries only when an upload fails so a rerun finishes a partial release; add a root Gradle task listing the published Gradle plugins.
  • Add the draft-release-notes.yml and release-dry-run.yml workflows, the notes draft, render, PR range, and version scripts, the android-release-wizard skill, dependency labels for Renovate and Dependabot, and the 1.10.0-SNAPSHOT development version; rewrite RELEASING.md.
  • Replace release.yml, draft-changelog.yml, the Buildkite dry run in ci.yml, and the previous release scripts.

@LikeTheSalad
LikeTheSalad requested a lite review from Copilot September 14, 2026 14:49
@github-actions

Copy link
Copy Markdown

🤖 GitHub comments

Just comment with:

  • run docs-build : Re-trigger the docs validation. (use unformatted text in the comment!)

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Critical release-path issues remain unresolved, including signing credentials, checkout pinning, publication guards, and plugin detection.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Automates Android releases through preparation and publication pull requests, replacing the manual release flow.

Changes:

  • Adds release preparation, publication, dry-run, and release-note workflows.
  • Adds versioning, rendering, guards, finalization, publishing, attestation, and follow-up PR tooling.
  • Updates documentation and configuration while removing legacy release tooling.
File summaries
File Change Review
skills/android-release-wizard/SKILL.md Documents the release wizard. Moderate (1 vote): Apostrophes in notes can break the single-quoted dispatch command; use shell-safe encoding or JSON/stdin input.
renovate.json Adds dependency labels. —
RELEASING.md Rewrites release instructions. —
gradle.properties Sets the next snapshot version. —
catalog-info.yaml Updates workflow links. —
build.gradle.kts Adds the plugin listing task. Critical (1 vote): The checked plugin ID may produce an empty list, causing a successful release without publishing; detect the appropriate plugin extension instead.
build-tools/src/main/java/co/elastic/otel/android/compilation/tools/publishing/ApmPublisherRootPlugin.java Excludes skill files from formatting. —
.github/workflows/release.yml Removes the legacy release workflow. —
.github/workflows/release-dry-run.yml Adds the release dry-run workflow. —
.github/workflows/README.md Links release documentation. —
.github/workflows/publish-release.yml Adds publication and finalization workflow. Critical (2 votes): The guard permits any merged PR targeting a releasing branch; require the matching preparation branch.
.github/workflows/prepare-release.yml Prepares release branches and PRs. Critical (1 vote): The checkout follows main instead of pinning github.sha, allowing unreviewed commits into the preparation branch.
.github/workflows/draft-release-notes.yml Adds release-note drafting workflow. —
.github/workflows/draft-changelog.yml Removes the legacy changelog workflow. —
.github/workflows/ci.yml Removes the embedded release dry run. —
.github/scripts/release/version.sh Implements version arithmetic. Moderate (1 vote): The tag glob accepts prerelease or malformed tags; filter with an anchored semantic-version expression.
.github/scripts/release/sample.json Adds a release-note sample. —
.github/scripts/release/render-release-notes.sh Renders and validates release notes. —
.github/scripts/release/publish-guard.sh Guards publication. —
.github/scripts/release/prepare-release.sh Creates preparation branches and PRs. —
.github/scripts/release/pr-range.sh Resolves included pull requests. —
.github/scripts/release/finalize-release.sh Finalizes releases and opens the main PR. Moderate (2 votes): Searching all PR states can select a closed prior PR and strand reruns; restrict to open PRs or reopen/create a replacement.
.github/scripts/release/draft-release-notes.sh Drafts categorized release notes. —
.github/scripts/generate-release-notes/script.main.kts Removes the legacy note generator. —
.github/scripts/generate-release-notes/sample.json Removes the legacy sample. —
.github/scripts/change-log/draft.sh Removes the legacy changelog script. —
.github/scripts/bump-minor-version/main.sh Removes the legacy version script. —
.github/dependabot.yml Adds dependency labels. —
.ci/release.sh Reworks publishing and artifact archiving. Critical (3 votes): Credential checks use variables not exported or consumed by the publisher, blocking Maven Central releases. Moderate (1 vote): Aggregate plugin retries cannot recover when only one of multiple Portal plugin IDs uploaded successfully.
Review details

Suppressed comments (3)

.ci/release.sh:118

  • The retry logic is project-level, but agent-plugin declares two Portal plugin IDs. If one ID uploads and the other fails, rerunning this aggregate publishPlugins task attempts the already-public ID again; the Portal rejects duplicate versions before the missing ID can be retried. The marker check below only observes the partial state after the task fails, so it cannot make this recovery path work. Publish/skip individual plugin IDs or otherwise make the aggregate task resume partial projects.
      if ./gradlew "$project_path:publishPlugins" \
        "-Pgradle.publish.key=$PLUGIN_PORTAL_KEY" \
        "-Pgradle.publish.secret=$PLUGIN_PORTAL_SECRET" \
        "${common_gradle_deploy_params[@]}"; then

.github/scripts/release/version.sh:45

  • This glob is not an exact vX.Y.Z filter: * and . also match tags such as v1.10.0-rc or malformed names. If such a tag sorts above the latest final release, parse_version aborts instead of selecting the highest release tag, so the release workflow cannot start. Filter the tag list with an anchored semantic-version expression before selecting the highest entry.
    tag=$(git tag --list 'v[0-9]*.[0-9]*.[0-9]*' --sort=-version:refname | head -n 1)

skills/android-release-wizard/SKILL.md:73

  • Substituting the approved JSON directly into single quotes makes this command fail whenever a release-note message contains an apostrophe (for example, user's). The skill should require shell-safe encoding/escaping of the inputs, or use a JSON/stdin form of gh workflow run, before dispatching a release.
  • Files reviewed: 30/31 changed files
  • Comments generated: 4
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .ci/release.sh Outdated
Comment thread .github/workflows/prepare-release.yml
Comment thread .github/workflows/publish-release.yml Outdated
Comment thread .github/scripts/release/finalize-release.sh Outdated
@LikeTheSalad
LikeTheSalad force-pushed the feature/android-release-automation branch from 676d62e to 69cbe6f Compare September 14, 2026 14:56
@LikeTheSalad LikeTheSalad changed the title Automate the release process with two pull requests Rework the release process around two pull requests Sep 14, 2026
@LikeTheSalad LikeTheSalad changed the title Rework the release process around two pull requests Enhance the release process Sep 14, 2026
@LikeTheSalad LikeTheSalad changed the title Enhance the release process Enhance the release process Sep 14, 2026
@LikeTheSalad
LikeTheSalad force-pushed the feature/android-release-automation branch from 69cbe6f to 3507a1c Compare September 14, 2026 15:04
@LikeTheSalad
LikeTheSalad requested a lite review from Copilot September 14, 2026 15:09

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Critical and moderate issues remain in release publication, concurrency, workflow authorization, note rendering, and dispatch handling.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (2)

.ci/release.sh:86

  • The recovery check is too coarse for a multi-module Maven publication. Each subproject registers its own publishAndReleaseElasticToMavenCentral task (build-tools/.../BaseApmPublisherPlugin.java:48-51), so a failed invocation can leave some artifacts public while agent-sdk is public. This check would then skip all Maven publishing on the rerun and leave the remaining modules unreleased; verify every Maven publication (or the Central deployment state) before treating the target as complete.
      # All modules go to Maven Central in one deployment that is released or
      # dropped as a whole, so one module's POM tells whether this version is
      # already public.
      central_pom="https://repo1.maven.org/maven2/co/elastic/otel/android/agent-sdk/$release_version/agent-sdk-$release_version.pom"

.github/workflows/publish-release.yml:22

  • This condition only checks the branch name, so a pull request from a fork whose branch is named prepare/<version> can also enter this privileged job once it is merged into releasing/<version>. The guard receives no head-repository identity and therefore cannot distinguish that case. Require github.event.pull_request.head.repo.full_name == github.repository here (or pass and validate it in the guard) so release credentials and publication are only reachable from the repository's preparation branch.
      && startsWith(github.event.pull_request.base.ref, 'releasing/')
      && startsWith(github.event.pull_request.head.ref, 'prepare/')
  • Files reviewed: 30/31 changed files
  • Comments generated: 5
  • Review effort level: Lite

Comment thread .ci/release.sh
Comment thread .github/workflows/prepare-release.yml
Comment thread skills/android-release-wizard/SKILL.md Outdated
Comment thread .github/scripts/release/render-release-notes.sh Outdated
Comment thread skills/android-release-wizard/SKILL.md

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Critical publication and release-note validation issues, plus retry and PR-range issues, remain unresolved.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (4)

.github/scripts/release/pr-range.sh:68

  • This exclusion list misses the legacy release branch names that are already in the repository's post-tag history. The current main history includes the merged post-release/1.9.0 PR, so the first migrated draft will emit that release-bookkeeping PR as a normal item instead of excluding it. Include the legacy post-release/* (and other old release/*/pre-release/*) prefixes here, or otherwise explicitly migrate those PRs out of the range.
  if [[ $head_ref == releasing/* || $head_ref == prepare/* ]]; then
    continue

.github/scripts/release/prepare-release.sh:46

  • This in-flight check makes preparation non-retryable after any failure that occurs after the first branch push. For example, if pushing prepare/$release_version or creating the PR fails after releasing/$release_version was created, a rerun sees that branch and exits here instead of reusing/finishing the same preparation. That leaves the release stranded despite the documented rerun recovery; make the branch/PR creation idempotent (or provide an explicit cleanup/recovery path).
existing_release_branches=$(git ls-remote --heads origin 'refs/heads/releasing/*' | awk '{print $2}')
if [[ -n $existing_release_branches ]]; then
  echo "A release is already in flight. Finish it, or delete its branches if it was abandoned:" >&2
  sed 's|refs/heads/|  |' <<<"$existing_release_branches" >&2
  exit 1

.github/workflows/publish-release.yml:65

  • The branch and SHA values are interpolated directly into shell source. Git ref names can contain shell metacharacters, so a PR whose head ref starts with prepare/ can close the quote and execute commands in this step while GH_TOKEN is available, before publish-guard.sh gets a chance to reject it. Pass event values through env and expand quoted shell variables instead of embedding them in run.
          .github/scripts/release/publish-guard.sh \
            "${{ github.event.pull_request.base.ref }}" \
            "${{ github.event.pull_request.head.ref }}" \
            "${{ github.event.pull_request.merge_commit_sha }}"

.github/workflows/publish-release.yml:118

  • The finalization command also embeds the pull request's base ref into shell source. Although the normal automation creates a numeric releasing/x.y.z branch, the workflow condition only checks a prefix, so a ref containing shell syntax can execute with GH_TOKEN before the script's version check. Pass the base ref (and the other arguments) via step env and use quoted variables here as well.
          .github/scripts/release/finalize-release.sh \
            "${{ steps.guard.outputs.release_sha }}" \
            "${{ steps.guard.outputs.release_version }}" \
            "${{ github.event.pull_request.base.ref }}" \
            "${{ steps.guard.outputs.publish_required }}"
  • Files reviewed: 30/31 changed files
  • Comments generated: 3
  • Review effort level: Lite

Comment thread .github/scripts/release/publish-guard.sh
Comment thread .github/scripts/release/render-release-notes.sh
Comment thread .github/workflows/publish-release.yml

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unresolved release automation issues affect input validation, recovery, PR-range calculation, and Plugin Portal publishing.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (2)

.ci/release.sh:50

  • These inputs are only checked for presence, not validity. A typo such as dry_run=flase or target_specifier=maven skips both publication branches, still archives artifacts, and exits 0, falsely reporting a successful release. Validate each value against the documented enum before entering the publishing logic.
if [[ $dry_run == false ]]; then

.github/scripts/release/pr-range.sh:69

  • The bookkeeping filter checks only the source branch name, not its repository. A legitimate pull request from a fork whose branch is named prepare/... or releasing/... will therefore be omitted from the release range and its change can be missing from the release notes. Exclude these prefixes only when .head.repo.full_name is the current repository.
  head_ref=$(jq -r '.head.ref' <<<"$pull_request")
  if [[ $head_ref == releasing/* || $head_ref == prepare/* ]]; then
    continue
  fi
  • Files reviewed: 30/31 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread .github/scripts/release/prepare-release.sh

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Critical release-safety and shell-injection issues, plus versioning gaps, remain unresolved.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (3)

.github/scripts/release/prepare-release.sh:63

  • The [Breaking] convention is documented as the signal that requires a major bump, but preparation never cross-checks it against BUMP. A manual dispatch with a [Breaking] note and bump=minor therefore publishes a breaking change under a minor version, defeating the workflow's version-safety guard. After parsing the notes, reject minor when any message starts with [Breaking] (and consider rejecting major without one).
notes_file="$work_dir/release-notes.json"
rendered_file="$work_dir/release-notes.md"
printf '%s\n' "$release_notes" | jq . >"$notes_file"
"$script_dir/render-release-notes.sh" "$notes_file" "$release_version" >"$rendered_file"

.github/scripts/release/version.sh:50

  • With set -euo pipefail, a repository with no exact vX.Y.Z tags makes grep return 1, so this command substitution exits the script before the explicit No release tag matching... check below can run. Make the filter tolerate no matches so tag can be checked and the intended error path remains reachable.
    tag=$(
      git tag --list 'v*' --sort=-version:refname \
        | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' \
        | head -n 1

RELEASING.md:6

  • This new guide sends operators to build-tools/README.md for publishing configuration, but that README still instructs them to set ORG_GRADLE_PROJECT_signingKey and ORG_GRADLE_PROJECT_signingPassword; the publisher actually reads SECRING_ASC and KEYPASS_SECRET (see build-tools/.../ApmPublisherPlugin.java:41-46 and .buildkite/hooks/pre-command:50-65). Update the linked documentation or remove this pointer so it does not send release operators to unusable credentials.
This guide describes how to publish EDOT Android to
[Maven Central](https://central.sonatype.com/) and the
[Gradle Plugin Portal](https://plugins.gradle.org/). For publishing
configuration details, see the [build-tools README](build-tools/README.md).
  • Files reviewed: 30/31 changed files
  • Comments generated: 6
  • Review effort level: Lite

Comment thread .ci/release.sh Outdated
Comment thread .github/scripts/release/finalize-release.sh
Comment thread .github/workflows/prepare-release.yml
Comment thread .github/workflows/publish-release.yml Outdated
Comment thread .github/workflows/publish-release.yml Outdated
Comment thread .github/workflows/publish-release.yml Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Critical release publication and finalization issues remain unresolved, along with legacy release-PR filtering.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (1)

.github/scripts/release/pr-range.sh:68

  • The first release prepared after this migration will still see the old workflow's post-release/<version> PR after the latest tag: the deleted workflow created that branch to bump gradle.properties on main. This filter only excludes the new releasing/* and prepare/* names, so draft-release-notes.sh will present that bookkeeping PR as a release-note item (and pr-range.sh will count it as a contribution). Exclude the legacy post-release/* branch pattern during the transition.
  if [[ $head_ref == releasing/* || $head_ref == prepare/* ]]; then
    continue
  • Files reviewed: 30/31 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment thread .ci/release.sh Outdated
Comment thread .github/scripts/release/finalize-release.sh
@LikeTheSalad
LikeTheSalad force-pushed the feature/android-release-automation branch from 410165f to 300aa84 Compare September 14, 2026 16:50

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Unresolved critical plugin discovery and moderate release-retry and release-notes input issues can block or misexecute releases.

Review details

Suppressed comments (2)

.ci/release.sh:155

  • This retries at project granularity, but agent-plugin declares two Portal plugins (agent-plugin/build.gradle.kts:50-65) and publishPlugins publishes the project as one task. If that task partially uploads one plugin and then fails, the next retry can fail again on the already-public plugin before reaching the missing one; the marker check below only reports the partial state after the task. Add a per-plugin retry path (or make the publish task skip already-public IDs) so the documented partial-release recovery can finish this project.
      if ./gradlew "$project_path:publishPlugins" \
        "-Pgradle.publish.key=$PLUGIN_PORTAL_KEY" \
        "-Pgradle.publish.secret=$PLUGIN_PORTAL_SECRET" \
        "${common_gradle_deploy_params[@]}"; then

skills/android-release-wizard/SKILL.md:85

  • -F/--field is the typed-field form: with release_notes=@"$notes", gh reads the JSON file as a structured value, while this workflow declares release_notes as a string input. The workflow dispatch can therefore reject the request or coerce the object instead of passing the JSON text to RELEASE_NOTES. Send the file contents through a raw string field (or otherwise quote the entire contents as one string).
  • Files reviewed: 31/32 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

The previous flow required typing the version, running the release
workflow by hand against a release branch, and merging a separate bump
pull request. Now Prepare release derives the version from the highest
tag, pushes a releasing/x.y.z branch from main, and opens a prepare/x.y.z
pull request into it with the release version, the release notes rendered
from the authored JSON, and the regenerated NOTICE files. Merging that
pull request publishes: Buildkite builds the merged commit once and
publishes to Maven Central and the Gradle Plugin Portal, GitHub attests
the artifacts, tags the commit, creates the GitHub Release, commits the
next -SNAPSHOT version on releasing/x.y.z, and opens the release pull
request into main. Nothing is merged by automation.

Add the android-release-wizard skill, a draft release-notes workflow, and
a release dry-run workflow; move the Buildkite dry run out of ci.yml;
label dependency updates; set the development version to 1.10.0-SNAPSHOT;
and replace the previous release workflows and scripts.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The critical plugin publication discovery and moderate legacy branch-filtering findings remain unresolved.

Review details

Suppressed comments (1)

.github/scripts/release/pr-range.sh:67

  • This migration still treats the previous release PR as a release-note item: the replaced release flow created its follow-up PR from post-release/<version>, and that PR is merged into main after the last release tag. Because only releasing/* and prepare/* are excluded here, the first draft after this change will include the old "Prepare for the next release" bookkeeping PR (as uncategorized) instead of omitting it. Exclude the legacy post-release/* head pattern while the repository transitions to the new branch names.
  if [[ $head_ref == releasing/* || $head_ref == prepare/* ]]; then
  • Files reviewed: 31/32 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The plugin publication issue and legacy bookkeeping filtering issue must be addressed.

Review details

Suppressed comments (1)

.github/scripts/release/pr-range.sh:69

  • This only filters the new releasing/* and prepare/* bookkeeping branches. The previous workflow in this PR created post-release/<version> (and release/*/pre-release/*) PRs, and the post-release version-bump PR is after the previous release tag, so the first draft will include that bookkeeping as a release change. Exclude the legacy bookkeeping branch names as well, otherwise operators must manually remove them and an otherwise empty release cannot take the no-op path.
  if [[ $head_ref == releasing/* || $head_ref == prepare/* ]]; then
    continue
  fi
  • Files reviewed: 31/32 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@LikeTheSalad

LikeTheSalad commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor Author

Quoted from the last Copilot message

This only filters the new releasing/* and prepare/* bookkeeping branches. The previous workflow in this PR created post-release/ (and release//pre-release/) PRs, and the post-release version-bump PR is after the previous release tag, so the first draft will include that bookkeeping as a release change.

This is as intended. It's basically saying that, since the new process uses a new set of branch name patterns different from the old one, that means that it will take the last release PRs as release notes candidates (since the filter that excludes PRs for release notes only takes into account the new release branch names). However, this will only happen once (in the next release), and I can manually exclude those by then, so I don't like the idea of adding a validation for a one-off use case.

@LikeTheSalad
LikeTheSalad marked this pull request as ready for review September 15, 2026 07:48
@LikeTheSalad
LikeTheSalad requested review from a team as code owners September 15, 2026 07:48

@v1v v1v left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I left a few comments, but didn't finish the whole review, but wanna provide a quick feedback here.

Comment thread .ci/release.sh Outdated
Comment thread .github/scripts/release/draft-release-notes.sh
Comment thread .github/scripts/release/finalize-release.sh
Comment thread .github/scripts/release/finalize-release.sh Outdated
Review feedback on the release process:

- .ci/release.sh treats a missing dry_run as true, so a trigger that does
  not ask to publish never publishes; only dry_run=false does.
- finalize-release.sh documents its arguments and the environment it needs
  (GITHUB_REPOSITORY, GH_TOKEN, optional GITHUB_SERVER_URL and
  GITHUB_OUTPUT) and refuses empty or malformed arguments before creating
  anything: the release SHA must be a full commit SHA, the version X.Y.Z,
  and create-tag true or false.
vishaangelova
vishaangelova previously approved these changes Sep 16, 2026

@vishaangelova vishaangelova left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM for the docs

Comment thread skills/android-release-wizard/SKILL.md Outdated
Comment thread RELEASING.md Outdated
RELEASING.md now describes what the android-release-wizard skill does
and links directly to it. The skill now instructs the agent to ensure
the local repository is current before drafting release notes.
Move the freshness check to the top of the skill so it also covers the
skill and script files themselves. Let the agent pick the up-to-date
main ref instead of assuming a remote named origin. Pin the gh commands
and the PR lookup to elastic/apm-agent-android so a fork clone or a
multi-remote checkout cannot resolve to another repository.
vishaangelova
vishaangelova previously approved these changes Sep 16, 2026

@vishaangelova vishaangelova left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM! 🚀

@v1v v1v left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just left a few minor comments

Comment thread .ci/release.sh Outdated
Comment thread .ci/release.sh Outdated
Comment thread .github/scripts/release/pr-range.sh
Comment thread .github/scripts/release/prepare-release.sh
Comment thread .github/scripts/release/publish-guard.sh
Comment thread .github/workflows/draft-release-notes.yml Outdated
Comment thread .github/workflows/prepare-release.yml Outdated
Comment thread .github/workflows/publish-release.yml Outdated
Comment thread .github/workflows/publish-release.yml
Comment thread .github/workflows/release-dry-run.yml
Keep both root build additions: the baseline Maven repository from #911
and the listPublishedGradlePlugins task the release script depends on.
@LikeTheSalad
LikeTheSalad merged commit fcd8296 into main Sep 23, 2026
15 checks passed
@LikeTheSalad
LikeTheSalad deleted the feature/android-release-automation branch September 29, 2026 07:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants