Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,13 @@ on:
- patch
- minor
- major
pull_request:
types:
- closed
permissions:
contents: write
pull-requests: write
jobs:
publish:
runs-on: ubuntu-latest
environment: production
if: github.event_name == 'workflow_dispatch' || (startsWith(github.event.pull_request.head.ref, 'release/') && github.event.pull_request.merged)
if: github.event_name == 'workflow_dispatch'
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
Expand Down
5 changes: 2 additions & 3 deletions DEVGUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,8 @@ When auto-tagging fails due to workflow file changes or other manual interventio

1. Merge PRs to master
2. Go to [publish.yml workflow](https://github.com/JuliaRegistries/TagBot/actions/workflows/publish.yml)
3. Run with desired version bump (major/minor/patch) — this builds and pushes the versioned Docker image (`ghcr.io/juliaregistries/tagbot:{version}`), updates `action.yml` with its SHA digest, and opens a release PR
4. Review and merge the created PR
5. CI tags the release, pushes floating Docker tags (`latest`, `{major}`, `{major}.{minor}`), and commits updated SHA pins to `example.yml`, `README.md`, and other doc files
3. Run with desired version bump (major/minor/patch) and approve the `production` environment gate
4. The workflow builds and pushes the versioned Docker image, commits the version bump to master, creates the Git tag and GitHub release, pushes floating Docker tags (`latest`, `{major}`, `{major}.{minor}`), and commits updated SHA pins to `example.yml`, `README.md`, and other doc files

---

Expand Down
57 changes: 18 additions & 39 deletions bin/publish.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from typing import List, Optional

from github import Auth, Github, GithubException
from github.PullRequest import PullRequest
from github.Repository import Repository
from semver import VersionInfo

Expand Down Expand Up @@ -47,22 +46,9 @@ def on_workflow_dispatch(version: str) -> None:
update_pyproject_toml(semver)
digest = build_and_push_versioned_image(semver)
update_action_yml(semver, digest)
branch = git_push(semver)
release_sha = git_commit(semver)
repo = GH.get_repo(REPO)
msg = f"Release {semver}"
repo.create_pull(title=msg, body=msg, head=branch, base="master")


def on_pull_request(number: int) -> None:
repo = GH.get_repo(REPO)
pr = repo.get_pull(number)
if not pr.merged or not pr.head.ref.startswith("release/"):
return
version = current_version()
tag_sha = pr.merge_commit_sha
git("fetch", "origin", "master")
git("checkout", "-B", "master", "origin/master")
update_action_ref_pins(version, tag_sha)
update_action_ref_pins(semver, release_sha)
git("add", "--all")
has_changes = (
subprocess.run(
Expand All @@ -71,10 +57,10 @@ def on_pull_request(number: int) -> None:
!= 0
)
if has_changes:
git("commit", "--message", f"Pin action refs to v{version}")
git("commit", "--message", f"Pin action refs to v{semver}")
git("push", "origin", "master")
update_tags(tag_sha)
create_release(repo, pr, tag_sha)
update_tags(release_sha)
create_release(repo, release_sha)
push_floating_tags()


Expand Down Expand Up @@ -125,13 +111,17 @@ def update_action_yml(version: VersionInfo, digest: str) -> None:
f.write(updated)


def git_push(version: VersionInfo) -> str:
branch = f"release/{version}"
msg = f"Release {version}"
git("checkout", "-B", branch)
git("commit", "--all", "--message", msg)
git("push", "origin", "--force", branch)
return branch
def git_commit(version: VersionInfo) -> str:
"""Commit the release changes to master and return the commit SHA."""
git("commit", "--all", "--message", f"Release {version}")
git("push", "origin", "master")
result = subprocess.run(
["git", "-C", WORKSPACE, "rev-parse", "HEAD"],
check=True,
capture_output=True,
text=True,
)
return result.stdout.strip()


def update_tags(commit: str) -> None:
Expand Down Expand Up @@ -169,14 +159,13 @@ def update_action_ref_pins(version: VersionInfo, sha: str) -> None:
f.write(updated)


def create_release(repo: Repository, pr: PullRequest, commit: str) -> None:
notes = get_release_notes(pr)
def create_release(repo: Repository, commit: str) -> None:
release = "v" + str(current_version())
try:
repo.create_git_release(
tag=release,
name=release,
message=notes,
message="",
target_commitish=commit,
generate_release_notes=True,
)
Expand All @@ -187,14 +176,6 @@ def create_release(repo: Repository, pr: PullRequest, commit: str) -> None:
raise


def get_release_notes(pr: PullRequest) -> str:
for comment in pr.get_issue_comments():
m = re.search("(?si)Release notes:(.*)", comment.body)
if m:
return m[1].strip()
return ""


def build_and_push_versioned_image(version: VersionInfo) -> str:
tag = f"{DOCKER_IMAGE}:{version}"
server = [DOCKER_IMAGE.split("/")[0]] if DOCKER_IMAGE.count("/") > 1 else []
Expand Down Expand Up @@ -256,5 +237,3 @@ def docker(*args: str, stdin: Optional[str] = None) -> None:
event = json.load(f)
if name == "workflow_dispatch":
on_workflow_dispatch(event["inputs"]["bump"])
elif name == "pull_request":
on_pull_request(event["pull_request"]["number"])