Skip to content

feat: implement automated release workflow#542

Open
shrutiyam-glitch wants to merge 9 commits intokubernetes-sigs:mainfrom
shrutiyam-glitch:automate-release
Open

feat: implement automated release workflow#542
shrutiyam-glitch wants to merge 9 commits intokubernetes-sigs:mainfrom
shrutiyam-glitch:automate-release

Conversation

@shrutiyam-glitch
Copy link
Copy Markdown
Contributor

@shrutiyam-glitch shrutiyam-glitch commented Apr 7, 2026

This Pull Request introduces an automated release workflow for the agent-sandbox repository, designed to streamline the process of promoting images and creating draft releases.

Fixes #408, #528

Summary
The changes implement a new GitHub Actions workflow that automates the manual steps required during a release. If the tag is not mentioned, the workflow creates the tag (auto -patching) and pushes the tag, promotes the images, waits for the promote PR to be merged and then generates the draft release.

Why
Previously, release engineers likely had to manually wait for image promotion PRs in the k8s.io repository to be merged before they could proceed with publishing a release. This automation reduces manual toil and the risk of human error by polling the PR status and proceeding only when the promotion is complete.
The only steps involving human intervention is merge the promote images PR and publish the final draft release.

How
New Workflow (.github/workflows/release.yml):

1. Triggering a Release

  • Scheduled: A patch release is automatically triggered every Friday at 06:00 UTC if new commits have been merged since the last tag.
  • Manual: Maintainers can manually trigger a release for any version (Major, Minor, or Patch) using the workflow_dispatch trigger in the Actions tab.

2. Versioning and Tagging
If no manual tag is provided, the dev/tools/auto-tag script calculates the next version by incrementing the patch number of the latest existing tag (e.g., v0.1.0 becomes v0.1.1). The workflow then creates and pushes this new tag to the repository.

3. Image Promotion (k8s.io)
The release process automatically handles the promotion of container images to the official Kubernetes registry:

  • The workflow clones and forks the kubernetes/k8s.io repository.
  • It runs make release-promote, which creates a Pull Request against kubernetes/k8s.io to stage and promote the new images.
  • The PR URL is saved and passed to the next stage of the pipeline.

4. Automated Polling
To ensure the release isn't published before images are available, a Poll PR Status job monitors the k8s.io Pull Request. It checks the PR state every 5 minutes for up to 12 hours. The workflow only proceeds once the PR is officially MERGED.

5. Draft Release Generation
Once images are promoted, the workflow generates a draft release:

  • AI-Generated Highlights: The dev/tools/generate-release-notes tool uses Gemini 2.5 Flash to summarize commit titles into professional release highlights.
  • Installation Manifests: The script automatically adds updated kubectl and pip installation commands tailored to the new version.
  • Draft Publication: Finally, it runs make release-publish to create a draft release on GitHub for final human review before public announcement.

Testing:
Tested the workflow by running it manually on my forked repository with hardcoded image names.

@netlify
Copy link
Copy Markdown

netlify bot commented Apr 7, 2026

Deploy Preview for agent-sandbox canceled.

Name Link
🔨 Latest commit 4ed1450
🔍 Latest deploy log https://app.netlify.com/projects/agent-sandbox/deploys/69e2c3fb23aed300088ef12f

@k8s-ci-robot
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: shrutiyam-glitch
Once this PR has been reviewed and has the lgtm label, please assign barney-s for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Apr 7, 2026
@shrutiyam-glitch shrutiyam-glitch marked this pull request as draft April 7, 2026 22:51
@k8s-ci-robot k8s-ci-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 7, 2026
@shrutiyam-glitch shrutiyam-glitch marked this pull request as ready for review April 7, 2026 23:27
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 7, 2026
Comment thread .github/workflows/release.yml Outdated
promote-and-wait:
name: Promote Images and Wait for PR
runs-on: ubuntu-latest
timeout-minutes: 360 # 6-hour limit for long k8s.io merge cycles
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.

Are these guaranteed to merge in 6 hrs ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I added as an estimate.
I looked at the previous PRs (https://github.com/kubernetes/k8s.io/pulls?q=is%3Apr+author%3Ajanetkuo+is%3Aclosed+label%3Algtm). It looks like a k8s member can approve it and usually a member from sandbox OSS has approved it on the same day.
What do you think is a good timeout here ?

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.

i dont have any good value for a timeout. There can be 2 options:

  1. More timeout: on same day for me is > 6hrs. Maybe 12 hrs. or even 24 hrs. But that seems excessive.
  2. Periodic script: Mostly no-op. Check if release made for most recent tag. if not release. if it fails thats fine. Next run will try again.

In anycase, we need to parameterize the script so that we can manully run the workflow as a backup with the tag passed as parameter.


- name: Clone k8s.io
env:
GH_TOKEN: ${{ secrets.K8S_IO_PAT }}
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.

Ensure the PAT uses Fine-Grained Permissions scoped exclusively to the kubernetes/k8s.io repository (or its fork) if possible. Limit access to contents: write and pull_requests: write.

Comment thread .github/workflows/release.yml Outdated
make release-promote TAG="${GITHUB_REF_NAME}" K8S_IO_DIR=../k8s.io | tee promote_output.log

# Extract the URL from the log
PR_URL=$(grep -o 'https://github.com/kubernetes/k8s.io/pull/[0-9]*' promote_output.log | head -n 1)
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.

Update the Makefile or promotion script to output the created PR URL directly to a structured file (e.g., echo $PR_URL > promote_pr.url) rather than relying on log output.

Comment thread .github/workflows/release.yml Outdated
@@ -0,0 +1,135 @@
name: Release Automation
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.

To test the workflow, you could try using act to simulate and run the GitHub Actions workflow inside local Docker containers, or add workflow_dispatch with a dry_run input parameter for manual, mutation-free cloud testing.

sleep 300
done

echo "❌ Timed out waiting for merge."
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.

Can the workflow be resumed manually if timed out, rather than restarting the entire promotion process?

Copy link
Copy Markdown
Contributor Author

@shrutiyam-glitch shrutiyam-glitch Apr 17, 2026

Choose a reason for hiding this comment

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

Yes, it can be restarted from the job - "poll-merge".

@aditya-shantanu
Copy link
Copy Markdown
Contributor

As discussed, add a timer trigger which takes a commit id/branch and tag as optional parameters.
As a separate PR - even before this one goes in, remove the testPyPi publish step. Given we have unit tests, that seems unnecessary.

@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Apr 16, 2026
@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Apr 17, 2026
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Apr 17, 2026
@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Apr 17, 2026
@shrutiyam-glitch shrutiyam-glitch changed the title feat: implement automated release workflow with image promotion polling feat: implement automated release workflow Apr 17, 2026
Copy link
Copy Markdown
Member

@janetkuo janetkuo left a comment

Choose a reason for hiding this comment

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

Thanks for the change!

remotes = run_command(["git", "remote"], cwd=cwd, capture_output=True).splitlines()
if "upstream" in remotes:
return "upstream"
return "origin"
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.

It's not safe to fall back to origin given that REMOTE_FORK is origin.
Also, it's not guaranteed that "origin" is in remotes, right?
Perhaps we throw an error here instead, asking users/runners to provide a value

We need to handle the REMOTE_FORK as well

# Version tag is incremented by patch update
schedule:
- cron: '0 6 * * 5' # Every Friday at 06:00 UTC
# For Major/Minor version updates, enter tag manually
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'm not sure I understand this comment, would you clarify?

Copy link
Copy Markdown
Contributor Author

@shrutiyam-glitch shrutiyam-glitch Apr 18, 2026

Choose a reason for hiding this comment

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

If no manual tag is provided, the dev/tools/auto-tag script calculates the next version by incrementing the patch number of the latest existing tag (e.g., v0.1.0 becomes v0.1.1). The workflow then creates and pushes this new tag to the repository.

For Major/Minor version updates (0.1.0->0.2.0 or 1.0.0) - need to enter the tag version in the input field during manual run of the workflow.

on:
# Version tag is incremented by patch update
schedule:
- cron: '0 6 * * 5' # Every Friday at 06:00 UTC
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.

Please remove this. I want to trigger this release workflow manually a few times before running it in cron. There are things like breaking changes that need to be introduced/handled more carefully.

Comment thread .github/workflows/pypi-publish.yml

url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key={api_key}"

prompt = f"You are a release assistant. Please summarize the following commit titles into a professional release note. Include an introductory paragraph highlighting the main achievements of this release, followed by a section called '### Key Highlights' with a bulleted list grouped logically. Keep it concise and focused on user-visible changes.\n\n{titles}"
Copy link
Copy Markdown
Member

@janetkuo janetkuo Apr 18, 2026

Choose a reason for hiding this comment

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

Breaking changes need to be in the release notes

Can it look at the PR comment? I asked folks who're introducing breaking changes to add that in the first PR comment, e.g. #440

The PRs introducing breaking changes have the release-note-action-required label

Also, here's the prompt I used to curate the release notes. You can't use it directly here because I asked my agent to look at the release notes page and release notes draft, but you can take part of it to update your prompt if you'd like to.

**Task:** Given a release version number, generate curated release notes for **Agent Sandbox release draft** from "What's Changed", following the structure and tone of the last official release.
> **1. Reference Format:**
> *   **Title:** ## 🚀 Announcing Agent Sandbox <version_number>!
> *   **Intro:** Brief summary of key improvements (documentation, observability, stability).
> *   **Sections:** 
>     *   `### Key Highlights` (Grouped by feature area with bold titles).
>     *   `### Installation` (Code blocks for `kubectl apply`).
>     *   `## Contributors` (thank them, and find their names from "What's Changed", and sort them by PR submission time)
>     *   `### 👋 New Contributors` (copy from draft).
>     *   `Full Changelog` (copy from draft).

# Get Gemini highlights
prev_tag = get_previous_tag(tag)
print(f"INFO: Found previous tag: {prev_tag}")
titles = get_commit_titles(prev_tag, tag)
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.

Can we read commit messages and the first comment of the PR (i.e. PR description), to get more information?

@@ -0,0 +1,170 @@
name: Scheduled Release Automation
Copy link
Copy Markdown
Member

@janetkuo janetkuo Apr 18, 2026

Choose a reason for hiding this comment

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

Have you tested the new scripts and the workflow? What tests/verification steps have you done? Would you provide an example release note that would be generated from main?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes. Added the info in the PR description.

Testing:
Tested the workflow by running it manually on my forked repository with hardcoded image names.

Promote Image job - https://github.com/shrutiyam-glitch/agent-sandbox-trial/actions/runs/24554049773/job/71786142560
Promote PR that was created in k8s repo - kubernetes/k8s.io#9354
Ran make release-publish script on local. Draft release generated - https://github.com/shrutiyam-glitch/agent-sandbox-trial/releases/tag/untagged-d5948cb2c139173f52b7

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 can't see drafts given that it's not public - would you publish https://github.com/shrutiyam-glitch/agent-sandbox-trial/releases/tag/untagged-d5948cb2c139173f52b7?

@k8s-ci-robot
Copy link
Copy Markdown
Contributor

@shrutiyam-glitch: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
presubmit-agent-sandbox-e2e-test 4ed1450 link true /test presubmit-agent-sandbox-e2e-test

Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Apr 18, 2026
@k8s-ci-robot
Copy link
Copy Markdown
Contributor

PR needs rebase.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Automate the release process

6 participants