diff --git a/.github/workflows/coolify-helper.yml b/.github/workflows/coolify-helper.yml index cf9eb4243..f5d0c3f0a 100644 --- a/.github/workflows/coolify-helper.yml +++ b/.github/workflows/coolify-helper.yml @@ -16,8 +16,53 @@ env: DOCKER_REGISTRY: docker.io IMAGE_NAME: "coollabsio/coolify-helper" +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + jobs: + check-version: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v5 + with: + persist-credentials: false + + - uses: docker/setup-buildx-action@v3 + + - name: Login to ${{ env.GITHUB_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.GITHUB_REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Ensure version is not published + run: | + BASE_VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getHelperVersion.php) + VERSION="${BASE_VERSION}" + for registry in "${DOCKER_REGISTRY}" "${GITHUB_REGISTRY}"; do + IMAGE="${registry}/${IMAGE_NAME}:${VERSION}" + if output=$(docker buildx imagetools inspect "$IMAGE" 2>&1); then + echo "::error::Version $VERSION already exists in $registry" + exit 1 + fi + if ! grep -Eqi 'manifest unknown|not found|no such manifest' <<< "$output"; then + echo "::error::Could not verify $IMAGE: $output" + exit 1 + fi + done + echo "Version $VERSION is available in both registries" + build-push: + needs: check-version strategy: matrix: include: diff --git a/.github/workflows/coolify-realtime.yml b/.github/workflows/coolify-realtime.yml index 538f5c992..881c44aab 100644 --- a/.github/workflows/coolify-realtime.yml +++ b/.github/workflows/coolify-realtime.yml @@ -16,8 +16,53 @@ env: DOCKER_REGISTRY: docker.io IMAGE_NAME: "coollabsio/coolify-realtime" +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + jobs: + check-version: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v5 + with: + persist-credentials: false + + - uses: docker/setup-buildx-action@v3 + + - name: Login to ${{ env.GITHUB_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.GITHUB_REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Ensure version is not published + run: | + BASE_VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getRealtimeVersion.php) + VERSION="${BASE_VERSION}" + for registry in "${DOCKER_REGISTRY}" "${GITHUB_REGISTRY}"; do + IMAGE="${registry}/${IMAGE_NAME}:${VERSION}" + if output=$(docker buildx imagetools inspect "$IMAGE" 2>&1); then + echo "::error::Version $VERSION already exists in $registry" + exit 1 + fi + if ! grep -Eqi 'manifest unknown|not found|no such manifest' <<< "$output"; then + echo "::error::Could not verify $IMAGE: $output" + exit 1 + fi + done + echo "Version $VERSION is available in both registries" + build-push: + needs: check-version strategy: matrix: include: diff --git a/tests/Unit/ProductionImageWorkflowTest.php b/tests/Unit/ProductionImageWorkflowTest.php index 793147511..488086526 100644 --- a/tests/Unit/ProductionImageWorkflowTest.php +++ b/tests/Unit/ProductionImageWorkflowTest.php @@ -60,6 +60,35 @@ it('runs support image workflows from main', function (string $workflowFile) { 'realtime' => 'coolify-realtime.yml', ]); +it('prevents the stable helper workflow from publishing an existing version', function () { + $workflow = file_get_contents(dirname(__DIR__, 2).'/.github/workflows/coolify-helper.yml'); + + expect($workflow) + ->toContain('check-version:') + ->toContain('needs: check-version') + ->toContain('VERSION="${BASE_VERSION}"') + ->toContain('docker buildx imagetools inspect "$IMAGE"') + ->toContain('Version $VERSION already exists in $registry') + ->toContain('Version $VERSION is available in both registries') + ->toContain('Could not verify $IMAGE') + ->toContain('cancel-in-progress: false'); +}); + +it('prevents the stable realtime workflow from publishing an existing version', function () { + $workflow = file_get_contents(dirname(__DIR__, 2).'/.github/workflows/coolify-realtime.yml'); + + expect($workflow) + ->toContain('check-version:') + ->toContain('needs: check-version') + ->toContain('php bootstrap/getRealtimeVersion.php') + ->toContain('VERSION="${BASE_VERSION}"') + ->toContain('docker buildx imagetools inspect "$IMAGE"') + ->toContain('Version $VERSION already exists in $registry') + ->toContain('Version $VERSION is available in both registries') + ->toContain('Could not verify $IMAGE') + ->toContain('cancel-in-progress: false'); +}); + it('generates the production changelog from main', function () { $workflow = file_get_contents(dirname(__DIR__, 2).'/.github/workflows/generate-changelog.yml');