From bdf811e3a331b1ecf56bc5ecca5732096e9b5aad Mon Sep 17 00:00:00 2001 From: Nick Gallegos Date: Tue, 29 Sep 2026 14:13:52 -0600 Subject: [PATCH 1/6] Add dry-run for testing push-docker-images # Conflicts: # .github/workflows/push-docker-images.yml --- .github/workflows/push-docker-images.yml | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/.github/workflows/push-docker-images.yml b/.github/workflows/push-docker-images.yml index 4ca7adb..a8eddc9 100644 --- a/.github/workflows/push-docker-images.yml +++ b/.github/workflows/push-docker-images.yml @@ -14,6 +14,13 @@ on: required: false type: string default: .github/docker-images.json + dry-run: + description: > + If true, skips registry logins and all actual pushes/description updates with loging of what would have happened + instead. + required: false + type: boolean + default: false permissions: contents: read packages: write @@ -80,17 +87,20 @@ jobs: - name: Checkout uses: actions/checkout@v7.0.1 - name: Log in to GitHub container registry + if: ${{ !inputs.dry-run }} uses: docker/login-action@v4.2.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Login to Docker Hub + if: ${{ !inputs.dry-run }} uses: docker/login-action@v4.2.0 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Set up Docker Buildx + if: ${{ !inputs.dry-run }} uses: docker/setup-buildx-action@v4.1.0 - name: Publish to Docker Hub run: | @@ -108,12 +118,19 @@ jobs: $tagsCLI = $tags -replace "^", "--tag particular/${name}:" $cmd = "docker buildx imagetools create $tagsCLI ghcr.io/particular/${name}:$sourceTag" Write-Output "Command: $cmd" - Invoke-Expression $cmd + if ('${{ inputs.dry-run }}' -eq 'true') + { + Write-Output "[dry-run] Skipping execution." + } + else + { + Invoke-Expression $cmd + } Write-Output "::endgroup::" } update-descriptions: - needs: [determine-image-configurations, push-to-container-registry] - if: ${{ needs.determine-image-configurations.outputs.latest == 'true' }} + needs: [determine-image-configurations, push] + if: ${{ needs.determine-image-configurations.outputs.latest == 'true' && !inputs.dry-run }} runs-on: ubuntu-latest name: Update Docker Hub description strategy: From 6100281774884cf41fe4a74658e8a078efc99ac6 Mon Sep 17 00:00:00 2001 From: Nick Gallegos Date: Wed, 30 Sep 2026 13:41:41 -0600 Subject: [PATCH 2/6] Add docker workflow tests --- .github/workflows/CI-workflows.yml | 9 ++++++++- .github/workflows/push-docker-images.yml | 2 +- .github/workflows/test-push-docker-images.yml | 11 +++++++++++ test/push-docker-images/valid-multi-image.json | 12 ++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/test-push-docker-images.yml create mode 100644 test/push-docker-images/valid-multi-image.json diff --git a/.github/workflows/CI-workflows.yml b/.github/workflows/CI-workflows.yml index 1aaa02d..10986f7 100644 --- a/.github/workflows/CI-workflows.yml +++ b/.github/workflows/CI-workflows.yml @@ -7,7 +7,14 @@ on: paths: - '.github/workflows/**' jobs: - test-workflows: + test-push-docker-images: + uses: ./.github/workflows/test-push-docker-images.yml + + validate-workflow-tests: + # So we can add new tests without having to update branch protection rules + name: CI - Workflows result + needs: [test-push-docker-images] + if: always() runs-on: ubuntu-latest defaults: run: diff --git a/.github/workflows/push-docker-images.yml b/.github/workflows/push-docker-images.yml index a8eddc9..01f5169 100644 --- a/.github/workflows/push-docker-images.yml +++ b/.github/workflows/push-docker-images.yml @@ -129,7 +129,7 @@ jobs: Write-Output "::endgroup::" } update-descriptions: - needs: [determine-image-configurations, push] + needs: [determine-image-configurations, push-to-container-registry] if: ${{ needs.determine-image-configurations.outputs.latest == 'true' && !inputs.dry-run }} runs-on: ubuntu-latest name: Update Docker Hub description diff --git a/.github/workflows/test-push-docker-images.yml b/.github/workflows/test-push-docker-images.yml new file mode 100644 index 0000000..c36a3fe --- /dev/null +++ b/.github/workflows/test-push-docker-images.yml @@ -0,0 +1,11 @@ +name: Test - push-docker-images +on: + workflow_call: +jobs: + test-valid: + name: valid config + uses: ./.github/workflows/push-docker-images.yml + with: + version: 1.2.3 + image-config-file: test/push-docker-images/valid-multi-image.json + dry-run: true diff --git a/test/push-docker-images/valid-multi-image.json b/test/push-docker-images/valid-multi-image.json new file mode 100644 index 0000000..529b520 --- /dev/null +++ b/test/push-docker-images/valid-multi-image.json @@ -0,0 +1,12 @@ +[ + { + "name": "servicecontrol", + "readme_filepath": "./src/ServiceControl/Container-README.md", + "short_description": "Gather status, performance and monitoring data for multiple endpoints from a single location." + }, + { + "name": "servicecontrol-audit", + "readme_filepath": "./src/ServiceControl.Audit/Container-README.md", + "short_description": "Provide valuable information about the message flow through a system." + } +] From dc060d5f3a068fa96ea881bbcbd2613238577812 Mon Sep 17 00:00:00 2001 From: Nick Gallegos Date: Wed, 30 Sep 2026 13:53:15 -0600 Subject: [PATCH 3/6] Fix rebase issue --- .github/workflows/CI-workflows.yml | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/.github/workflows/CI-workflows.yml b/.github/workflows/CI-workflows.yml index 10986f7..6c41fc4 100644 --- a/.github/workflows/CI-workflows.yml +++ b/.github/workflows/CI-workflows.yml @@ -10,23 +10,10 @@ jobs: test-push-docker-images: uses: ./.github/workflows/test-push-docker-images.yml - validate-workflow-tests: - # So we can add new tests without having to update branch protection rules - name: CI - Workflows result - needs: [test-push-docker-images] - if: always() - runs-on: ubuntu-latest - defaults: - run: - shell: pwsh - steps: - - name: Placeholder - run: echo "Placeholder for testing workflows" - validate-workflow-tests: # So we can add new tests without having to update branch protection rules name: Validate workflow test results - needs: [test-workflows] + needs: [test-push-docker-images] if: always() runs-on: ubuntu-latest defaults: From d0f55c428e3dc82cdaadbdf4df67f2692c42720e Mon Sep 17 00:00:00 2001 From: Nick Gallegos Date: Wed, 30 Sep 2026 15:15:47 -0600 Subject: [PATCH 4/6] Add tests for determine-image-tags action --- .github/workflows/CI-actions.yml | 12 +-- .../workflows/test-determine-image-tags.yml | 88 +++++++++++++++++++ 2 files changed, 91 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/test-determine-image-tags.yml diff --git a/.github/workflows/CI-actions.yml b/.github/workflows/CI-actions.yml index 0546aa1..7e1aa55 100644 --- a/.github/workflows/CI-actions.yml +++ b/.github/workflows/CI-actions.yml @@ -7,19 +7,13 @@ on: paths: - '.github/actions/**' jobs: - test-actions: - runs-on: ubuntu-latest - defaults: - run: - shell: pwsh - steps: - - name: Placeholder - run: echo "Placeholder for testing actions" + test-determine-image-tags: + uses: ./.github/workflows/test-determine-image-tags.yml validate-action-tests: # So we can add new tests without having to update branch protection rules name: Validate action test results - needs: [test-actions] + needs: [test-determine-image-tags] if: always() runs-on: ubuntu-latest defaults: diff --git a/.github/workflows/test-determine-image-tags.yml b/.github/workflows/test-determine-image-tags.yml new file mode 100644 index 0000000..d63d9e2 --- /dev/null +++ b/.github/workflows/test-determine-image-tags.yml @@ -0,0 +1,88 @@ +name: Test - determine-image-tags +on: + workflow_call: +jobs: + test-determine-image-tags: + name: determine-image-tags / ${{ matrix.scenario }} + runs-on: ubuntu-latest + defaults: + run: + shell: pwsh + strategy: + fail-fast: false + matrix: + include: + - scenario: release version + version: 9.9.9 + expect-failure: false + - scenario: prerelease version + version: 9.9.9-beta.1 + expect-failure: false + - scenario: invalid version + version: not-a-version + expect-failure: true + steps: + - name: Checkout + uses: actions/checkout@v7.0.1 + - name: Determine image tags + id: tags + continue-on-error: ${{ matrix.expect-failure }} + uses: ./.github/actions/determine-image-tags + with: + version: ${{ matrix.version }} + - name: Verify + run: | + $version = '${{ matrix.version }}' + $expectFailure = '${{ matrix.expect-failure }}' -eq 'true' + $outcome = '${{ steps.tags.outcome }}' + + if ($expectFailure) + { + if ($outcome -ne 'failure') + { + throw "Expected determine-image-tags to fail for version '$version', but outcome was '$outcome'." + } + Write-Output "OK: failed as expected ($outcome)" + exit 0 + } + + if ($outcome -ne 'success') + { + throw "Expected determine-image-tags to succeed for version '$version', but outcome was '$outcome'." + } + + $isMatch = $version -match '^(?\d+)\.(?\d+)\.(?\d+)(-(?[\w\-\.]+))?$' + $expectedMajor = $Matches.Major + $expectedMinor = $Matches.Minor + $expectedPatch = $Matches.Patch + # Cast to [string] because GitHub actions output empty strings but unmatched groups are null + $expectedPrerelease = [string]$Matches.PrereleaseLabel + + $major = '${{ steps.tags.outputs.major }}' + $minor = '${{ steps.tags.outputs.minor }}' + $patch = '${{ steps.tags.outputs.patch }}' + $prerelease = '${{ steps.tags.outputs.prerelease }}' + $imageTags = '${{ steps.tags.outputs.image-tags }}' -split ',' + $latest = '${{ steps.tags.outputs.latest }}' + + Write-Output "major=$major minor=$minor patch=$patch prerelease=$prerelease image-tags=$imageTags latest=$latest" + + if ($major -ne $expectedMajor) { throw "Expected major '$expectedMajor', got '$major'." } + if ($minor -ne $expectedMinor) { throw "Expected minor '$expectedMinor', got '$minor'." } + if ($patch -ne $expectedPatch) { throw "Expected patch '$expectedPatch', got '$patch'." } + if ($prerelease -ne $expectedPrerelease) { throw "Expected prerelease '$expectedPrerelease', got '$prerelease'." } + if ($imageTags -notcontains $version) { throw "Expected image-tags to include the version itself ('$version'), got: $imageTags" } + + if ($expectedPrerelease) + { + # Prerelease versions never get floating tags - only the version itself. + if ($imageTags.Count -ne 1) { throw "Expected a prerelease version to produce exactly one tag, got: $imageTags" } + } + else + { + # The action uses this repo's release history, so just make sure we see the expected values since we + # can't reliably test exact scenarios without making a mess of the releases + if ($latest -ne 'true' -and $latest -ne 'false') { throw "Expected latest to be 'true' or 'false', got '$latest'." } + } + + Write-Output "OK" From d545c5c3b125128d2b4bf06a980acbc6963c025c Mon Sep 17 00:00:00 2001 From: Nick Gallegos Date: Thu, 1 Oct 2026 15:30:31 -0600 Subject: [PATCH 5/6] Clean up job name --- .github/workflows/test-determine-image-tags.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-determine-image-tags.yml b/.github/workflows/test-determine-image-tags.yml index d63d9e2..af9f90a 100644 --- a/.github/workflows/test-determine-image-tags.yml +++ b/.github/workflows/test-determine-image-tags.yml @@ -3,7 +3,7 @@ on: workflow_call: jobs: test-determine-image-tags: - name: determine-image-tags / ${{ matrix.scenario }} + name: ${{ matrix.scenario }} runs-on: ubuntu-latest defaults: run: From d6bc7279224d41c5ac296dc156e7e514e4af9434 Mon Sep 17 00:00:00 2001 From: Nick Gallegos Date: Fri, 2 Oct 2026 10:07:02 -0600 Subject: [PATCH 6/6] Add test for single image config file --- .github/workflows/test-push-docker-images.yml | 12 ++++++++++-- test/push-docker-images/valid-single-image.json | 7 +++++++ 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 test/push-docker-images/valid-single-image.json diff --git a/.github/workflows/test-push-docker-images.yml b/.github/workflows/test-push-docker-images.yml index c36a3fe..613c0da 100644 --- a/.github/workflows/test-push-docker-images.yml +++ b/.github/workflows/test-push-docker-images.yml @@ -3,9 +3,17 @@ on: workflow_call: jobs: test-valid: - name: valid config + name: valid config (${{ matrix.scenario }}) + strategy: + fail-fast: false + matrix: + include: + - scenario: single image + image-config-file: test/push-docker-images/valid-single-image.json + - scenario: multiple images + image-config-file: test/push-docker-images/valid-multi-image.json uses: ./.github/workflows/push-docker-images.yml with: version: 1.2.3 - image-config-file: test/push-docker-images/valid-multi-image.json + image-config-file: ${{ matrix.image-config-file }} dry-run: true diff --git a/test/push-docker-images/valid-single-image.json b/test/push-docker-images/valid-single-image.json new file mode 100644 index 0000000..49b8f4c --- /dev/null +++ b/test/push-docker-images/valid-single-image.json @@ -0,0 +1,7 @@ +[ + { + "name": "servicepulse", + "readme_filepath": "./Container-README.md", + "short_description": "Keep track of the health and performance of your system's endpoints." + } +]