From ef4470e58fa9ce18ba238e0ba2e0f207455b7135 Mon Sep 17 00:00:00 2001 From: Petar Shtuchkin Date: Fri, 3 Oct 2025 13:50:30 +0300 Subject: [PATCH 1/4] Do not push to official library by default --- .github/workflows/release_publish.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release_publish.yml b/.github/workflows/release_publish.yml index 53656054f..3c2f79ca5 100644 --- a/.github/workflows/release_publish.yml +++ b/.github/workflows/release_publish.yml @@ -11,6 +11,8 @@ on: workflow_uuid: description: 'Optional UUID to identify this workflow run' required: false + pr_to_official_library: + default: false env: TARGET_OFFICIAL_IMAGES_REPO: docker-library/official-images @@ -76,7 +78,7 @@ jobs: uses: actions/checkout@v4 with: path: official-images - repository: ${{ env.TARGET_OFFICIAL_IMAGES_REPO }} + repository: ${{ github.event.inputs.pr_to_official_library && env.TARGET_OFFICIAL_IMAGES_REPO || env.FORKED_OFFICIAL_IMAGES_REPO }} - name: Generate stackbrew library content env: @@ -102,7 +104,7 @@ jobs: with: token: ${{ secrets.GH_TOKEN_FOR_PR }} draft: true - push-to-fork: ${{ env.FORKED_OFFICIAL_IMAGES_REPO }} + push-to-fork: ${{ github.event.inputs.pr_to_official_library && env.FORKED_OFFICIAL_IMAGES_REPO || '' }} path: official-images branch: redis-${{ steps.parse-release.outputs.release_version }} commit-message: "Redis: Update to ${{ steps.parse-release.outputs.release_version }}" @@ -158,4 +160,4 @@ jobs: . ${GITHUB_WORKSPACE}/.github/actions/common/func.sh slack_format_failure_message "Docker PR failed for Redis: ${{ steps.parse-release.outputs.release_version || 'unknown'}}" "$workflow_url" "$footer" \ - | curl -s --fail-with-body -d@- "${{ secrets.SLACK_WEB_HOOK_URL }}" \ No newline at end of file + | curl -s --fail-with-body -d@- "${{ secrets.SLACK_WEB_HOOK_URL }}" From be54e5f83dcb72a1a7886047718d919eeb075107 Mon Sep 17 00:00:00 2001 From: Petar Shtuchkin Date: Fri, 3 Oct 2025 14:30:03 +0300 Subject: [PATCH 2/4] Fix publish image in pre-merge workflow --- .github/workflows/pre-merge.yml | 7 ++++++- .github/workflows/release_build_and_test.yml | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pre-merge.yml b/.github/workflows/pre-merge.yml index f4959d046..2f363aff5 100644 --- a/.github/workflows/pre-merge.yml +++ b/.github/workflows/pre-merge.yml @@ -11,6 +11,11 @@ on: description: 'Release tag to build' required: true type: string + publish_image: + description: 'Publish Docker image to GHCR' + required: false + type: boolean + default: false outputs: docker_image_urls: description: 'Array of Docker image URLs that were published' @@ -60,7 +65,7 @@ jobs: platform: ${{ matrix.platform }} registry_username: ${{ github.actor }} registry_password: ${{ secrets.GITHUB_TOKEN }} - publish_image: ${{ vars.PUBLISH_IMAGE }} + publish_image: ${{ inputs.publish_image || vars.PUBLISH_IMAGE }} registry_repository: ${{ format('ghcr.io/{0}', github.repository) }} release_tag: ${{ inputs.release_tag }} diff --git a/.github/workflows/release_build_and_test.yml b/.github/workflows/release_build_and_test.yml index bfbdfe31a..41299fb8d 100644 --- a/.github/workflows/release_build_and_test.yml +++ b/.github/workflows/release_build_and_test.yml @@ -57,6 +57,7 @@ jobs: secrets: inherit with: release_tag: ${{ github.event.inputs.release_tag }} + publish_image: true merge-back-to-release-branch: needs: [prepare-release, build-and-test] From 170c204f7116e3bf4bb6becaa70a5dac17e84624 Mon Sep 17 00:00:00 2001 From: Petar Shtuchkin Date: Fri, 3 Oct 2025 15:45:06 +0300 Subject: [PATCH 3/4] Fix pr_to_official condition --- .github/workflows/release_publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release_publish.yml b/.github/workflows/release_publish.yml index 3c2f79ca5..c57fe9d24 100644 --- a/.github/workflows/release_publish.yml +++ b/.github/workflows/release_publish.yml @@ -78,7 +78,7 @@ jobs: uses: actions/checkout@v4 with: path: official-images - repository: ${{ github.event.inputs.pr_to_official_library && env.TARGET_OFFICIAL_IMAGES_REPO || env.FORKED_OFFICIAL_IMAGES_REPO }} + repository: ${{ github.event.inputs.pr_to_official_library == 'true' && env.TARGET_OFFICIAL_IMAGES_REPO || env.FORKED_OFFICIAL_IMAGES_REPO }} - name: Generate stackbrew library content env: @@ -104,7 +104,7 @@ jobs: with: token: ${{ secrets.GH_TOKEN_FOR_PR }} draft: true - push-to-fork: ${{ github.event.inputs.pr_to_official_library && env.FORKED_OFFICIAL_IMAGES_REPO || '' }} + push-to-fork: ${{ github.event.inputs.pr_to_official_library == 'true' && env.FORKED_OFFICIAL_IMAGES_REPO || '' }} path: official-images branch: redis-${{ steps.parse-release.outputs.release_version }} commit-message: "Redis: Update to ${{ steps.parse-release.outputs.release_version }}" From 08ae1915558a99beb9c8e193b6bc1c56e9078f84 Mon Sep 17 00:00:00 2001 From: Petar Shtuchkin Date: Fri, 3 Oct 2025 18:50:53 +0300 Subject: [PATCH 4/4] Use actual repo (peeled) commits instead of annotated tag hashes --- .../src/stackbrew_generator/git_operations.py | 23 +++++++++-- .../tests/test_git_operations.py | 41 +++++++++++++++++++ 2 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 release-automation/tests/test_git_operations.py diff --git a/release-automation/src/stackbrew_generator/git_operations.py b/release-automation/src/stackbrew_generator/git_operations.py index 14dab035c..493c7e4a4 100644 --- a/release-automation/src/stackbrew_generator/git_operations.py +++ b/release-automation/src/stackbrew_generator/git_operations.py @@ -67,7 +67,7 @@ def list_remote_tags(self, major_version: int) -> List[Tuple[str, str]]: console.print(f"[dim]Listing remote tags for v{major_version}.*[/dim]") cmd = [ - "git", "ls-remote", "--refs", "--tags", + "git", "ls-remote", "--tags", self.remote, f"refs/tags/v{major_version}.*" ] @@ -76,11 +76,28 @@ def list_remote_tags(self, major_version: int) -> List[Tuple[str, str]]: if not result.stdout.strip(): raise GitOperationError(f"No tags found for major version {major_version}") - tags = [] + tag_commits = {} + + # always use peeled commits for annotated tags + # for annotated tags git ls-remote prints tag object hash, then actual commit hash with ^{} suffix + # https://stackoverflow.com/a/25996877 for line in result.stdout.strip().split('\n'): if line: commit, ref = line.split('\t', 1) - tags.append((commit, ref)) + if ref.endswith('^{}'): + # This is a peeled ref - extract the tag name + # always rewrite tag commits with peeled ref commits + tag_name = ref[:-3] # Remove '^{}' + tag_commits[tag_name] = commit + else: + # This is a regular tag + # rewrite only if not yet exists + if ref not in tag_commits: + tag_commits[ref] = commit + + tags = [] + for tag_ref, commit in tag_commits.items(): + tags.append((commit, tag_ref)) console.print(f"[dim]Found {len(tags)} tags[/dim]") return tags diff --git a/release-automation/tests/test_git_operations.py b/release-automation/tests/test_git_operations.py new file mode 100644 index 000000000..fddf2f4cb --- /dev/null +++ b/release-automation/tests/test_git_operations.py @@ -0,0 +1,41 @@ +"""Tests for git operations.""" + +from unittest.mock import Mock, patch + +from stackbrew_generator.git_operations import GitClient + + +class TestGitClient: + """Tests for GitClient class.""" + + @patch('stackbrew_generator.git_operations.console') + @patch.object(GitClient, '_run_command') + def test_list_remote_tags(self, mock_run_command, mock_console): + """ + Test that list_remote_tags returns the expected format for peeled refs. + + For tags with ^{} suffix, use the commit hash from that line. + For tags without ^{} suffix, use the commit hash from the tag line. + """ + mock_result = Mock() + mock_result.stdout = """101262a8cf05b98137d88bc17e77db90c24cc783\trefs/tags/v8.0.3 +2277e5ead99f0caacbd90e0d04693adb27ebfaa6\trefs/tags/v8.0.4^{} +c0125f5be8786d556a9d3edd70f51974fe045c1a\trefs/tags/v8.0.4 +f76d8a1cc979be6202aed93efddd2a0ebbfa0209\trefs/tags/v8.2.2 +c5846c13383c8b284897ff171e0c946868ed4c8c\trefs/tags/v8.2.2^{}""" + mock_run_command.return_value = mock_result + + client = GitClient() + result = client.list_remote_tags(8) + + # Expected behavior: + # - v8.0.3 has no peeled ref, so use the tag commit + # - v8.0.4 has a peeled ref, so use the peeled commit (2277e5ead99f0caacbd90e0d04693adb27ebfaa6) + # - v8.2.2 has a peeled ref, so use the peeled commit (c5846c13383c8b284897ff171e0c946868ed4c8c) + expected_result = [ + ("101262a8cf05b98137d88bc17e77db90c24cc783", "refs/tags/v8.0.3"), # No peeled ref + ("2277e5ead99f0caacbd90e0d04693adb27ebfaa6", "refs/tags/v8.0.4"), # Use peeled ref + ("c5846c13383c8b284897ff171e0c946868ed4c8c", "refs/tags/v8.2.2") # Use peeled ref + ] + + assert result == expected_result