-
Notifications
You must be signed in to change notification settings - Fork 6
refactor: update GitHub workflows for release management and image build #97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: refactor/prod-and-dev-Dockerfiles
Are you sure you want to change the base?
Conversation
…ilding - Added new workflows for creating releases, preparing releases, and publishing libraries on merge. - Implemented logic to derive version from pull request titles and create Git tags/releases accordingly. - Enhanced image building workflows to include digest capturing and improved error handling. - Refactored existing workflows to streamline the process of bumping versions for internal libraries and services. - Introduced scripts for bumping chart versions and updating pyproject dependencies. - Removed obsolete scripts and workflows to clean up the repository.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request refactors the release automation from a single monolithic workflow to a modular approach with label-based gating. It removes the legacy semantic-release workflow and introduces specialized workflows for each stage of the release process, along with new Python utilities for dependency and version management.
- Split release automation into 5 specialized workflows with label-based gating
- Added Python utilities for version bumping, dependency management, and chart updates
- Updated service names and versions to align with new release structure
Reviewed Changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.
Show a summary per file
File | Description |
---|---|
tools/update-helm-values.py | Removed legacy Helm values update script |
tools/bump_pyproject_deps.py | Added utility for managing Python library versions and service dependency pins |
tools/bump_chart_versions.py | Added utility for converting app versions to Helm chart versions |
services/*/pyproject.toml | Updated service names and versions for consistency |
.github/workflows/semantic-release.yml | Removed monolithic release workflow |
.github/workflows/*.yml | Added modular workflows for prepare-release, publish-libs, build-images, create-release, and publish-chart |
.github/workflows/lint-and-test.yml | Added label-based gating to skip CI during release automation |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
uses: azure/setup-helm@v4 | ||
|
||
- name: Login to GHCR for Helm OCI | ||
run: echo ${{ secrets.GHCR_PAT }} | helm registry login ghcr.io -u ${{ github.actor }} --password-stdin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The GHCR_PAT secret is being echoed directly in the pipeline output, which could expose the token in logs. Use the helm registry login command with the --password-stdin flag correctly by piping from a secure environment variable instead.
run: echo ${{ secrets.GHCR_PAT }} | helm registry login ghcr.io -u ${{ github.actor }} --password-stdin | |
run: printf "%s" "${{ secrets.GHCR_PAT }}" | helm registry login ghcr.io -u ${{ github.actor }} --password-stdin |
Copilot uses AI. Check for mistakes.
tag_name: v${{ steps.ver.outputs.version }} | ||
name: v${{ steps.ver.outputs.version }} | ||
generate_release_notes: true | ||
token: ${{ secrets.GHCR_PAT }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using GHCR_PAT token for GitHub release creation is inconsistent. The standard GITHUB_TOKEN should be sufficient for creating releases and would be more appropriate here.
token: ${{ secrets.GHCR_PAT }} | |
token: ${{ secrets.GITHUB_TOKEN }} |
Copilot uses AI. Check for mistakes.
with: | ||
registry: ghcr.io | ||
username: ${{ github.actor }} | ||
password: ${{ secrets.GHCR_PAT }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using GHCR_PAT for Docker registry authentication is inconsistent with GitHub's recommended approach. The standard GITHUB_TOKEN should be sufficient for pushing to ghcr.io.
password: ${{ secrets.GHCR_PAT }} | |
password: ${{ secrets.GITHUB_TOKEN }} |
Copilot uses AI. Check for mistakes.
for i, line in enumerate(lines): | ||
stripped = line.strip() | ||
if stripped.startswith('[tool.poetry]'): | ||
in_tool_poetry = True | ||
continue | ||
if in_tool_poetry and stripped.startswith('[') and not stripped.startswith('[tool.poetry]'): | ||
# left the section without finding version; stop scanning section | ||
break | ||
if in_tool_poetry and stripped.startswith('version'): | ||
# Replace only the version value, keep indentation and spacing | ||
lines[i] = re.sub(r'version\s*=\s*"[^"]*"', f'version = "{new_version}"', line) | ||
return ''.join(lines) | ||
# If no version line found, append it to the [tool.poetry] section |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fallback adds a duplicate [tool.poetry] section when no version line is found, which would create invalid TOML. The logic should append the version line to an existing [tool.poetry] section or handle the case where the section doesn't exist properly.
for i, line in enumerate(lines): | |
stripped = line.strip() | |
if stripped.startswith('[tool.poetry]'): | |
in_tool_poetry = True | |
continue | |
if in_tool_poetry and stripped.startswith('[') and not stripped.startswith('[tool.poetry]'): | |
# left the section without finding version; stop scanning section | |
break | |
if in_tool_poetry and stripped.startswith('version'): | |
# Replace only the version value, keep indentation and spacing | |
lines[i] = re.sub(r'version\s*=\s*"[^"]*"', f'version = "{new_version}"', line) | |
return ''.join(lines) | |
# If no version line found, append it to the [tool.poetry] section | |
tool_poetry_start = None | |
tool_poetry_end = None | |
version_found = False | |
for i, line in enumerate(lines): | |
stripped = line.strip() | |
if stripped.startswith('[tool.poetry]'): | |
in_tool_poetry = True | |
tool_poetry_start = i | |
continue | |
if in_tool_poetry and stripped.startswith('[') and not stripped.startswith('[tool.poetry]'): | |
# left the section without finding version; stop scanning section | |
tool_poetry_end = i | |
in_tool_poetry = False | |
break | |
if in_tool_poetry and stripped.startswith('version'): | |
# Replace only the version value, keep indentation and spacing | |
lines[i] = re.sub(r'version\s*=\s*"[^"]*"', f'version = "{new_version}"', line) | |
version_found = True | |
return ''.join(lines) | |
# If [tool.poetry] section exists but no version line found, insert it | |
if tool_poetry_start is not None: | |
insert_at = tool_poetry_start + 1 | |
# If we found the end of the section, insert before it | |
if tool_poetry_end is not None: | |
insert_at = tool_poetry_end | |
# Determine indentation (match other lines in section, or default to 4 spaces) | |
indent = "" | |
for j in range(tool_poetry_start + 1, (tool_poetry_end or len(lines))): | |
content = lines[j].lstrip('\r\n') | |
if content and not content.strip().startswith('['): | |
indent = lines[j][:len(lines[j]) - len(lines[j].lstrip())] | |
break | |
lines.insert(insert_at, f"{indent}version = \"{new_version}\"\n") | |
return ''.join(lines) | |
# If no [tool.poetry] section found, append it at the end |
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
This pull request restructures and improves the release automation for the repository by splitting the previous monolithic workflow into several specialized GitHub Actions workflows. These new workflows automate versioning, library publishing, Docker image building, Helm chart packaging, and dependency lockfile refreshing. Additionally, the workflows now use label-based gating to control releases and dependency updates, and they improve version extraction and artifact handling. The previous workflow file
.github/workflows/semantic-release.yml
has been removed and replaced with more maintainable, modular workflows.Release and Versioning Automation
.github/workflows/prepare-release.yml
to automate semantic version calculation and bump internal library versions, opening a PR with the new versions and gating future steps with theprepare-release
label..github/workflows/create-release.yml
to create a Git tag and GitHub Release when a PR with therefresh-locks
label is merged tomain
, extracting the version from the PR title.Library Publishing and Dependency Management
.github/workflows/publish-libs-on-merge.yml
to publish Python libraries to TestPyPI after aprepare-release
PR is merged, update service dependency pins, refresh lockfiles, and open a PR with updated lockfiles using therefresh-locks
label.Docker Image and Helm Chart Automation
.github/workflows/build-images.yml
to build and publish Docker images for all services when a release is published, capturing image digests as artifacts..github/workflows/publish-chart.yml
to package and publish the Helm chart after images are built, bumping chart versions and opening a PR for chart version updates using thechart-bump
label.Workflow Gating and Cleanup
.github/workflows/lint-and-test.yml
to skip jobs if any of the release-related labels (prepare-release
,refresh-locks
,chart-bump
) are present, preventing unnecessary CI runs during release automation..github/workflows/semantic-release.yml
workflow, which previously handled all release steps in one file, in favor of the new modular approach.These changes collectively make the release process more robust, modular, and maintainable, while ensuring that versioning, publishing, and dependency updates are tightly controlled and automated.