diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml new file mode 100644 index 0000000..0cb729a --- /dev/null +++ b/.github/actionlint.yaml @@ -0,0 +1,13 @@ +self-hosted-runner: + # Labels of self-hosted runner in array of string + labels: + - bastion + - x86_64 + - arm64 + - aarch64 + - amd64 + - repo-nightly + - repo-staging + - repo-release + - medium + - large diff --git a/.github/actions/action.yml b/.github/actions/action.yml new file mode 100644 index 0000000..6605d5d --- /dev/null +++ b/.github/actions/action.yml @@ -0,0 +1,33 @@ +--- +name: setup-actionlint +description: Setup actionlint +inputs: + version: + description: The version of actionlint + default: 1.6.24 + cache-seed: + required: true + type: string + description: Seed used to invalidate caches + +runs: + using: composite + steps: + + - name: Cache actionlint Binary + uses: actions/cache@v3 + with: + path: /usr/local/bin/actionlint + key: ${{ inputs.cache-seed }}|${{ runner.os }}|${{ runner.arch }}|actionlint|${{ inputs.version }} + + - name: Setup actionlint + shell: bash + run: | + if ! command -v actionlint; then + bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) ${{ inputs.version }} + mv ./actionlint /usr/local/bin/actionlint + fi + - name: Show actionlint Version + shell: bash + run: | + actionlint --version diff --git a/.github/actions/setup-actionlint/action.yml b/.github/actions/setup-actionlint/action.yml new file mode 100644 index 0000000..6605d5d --- /dev/null +++ b/.github/actions/setup-actionlint/action.yml @@ -0,0 +1,33 @@ +--- +name: setup-actionlint +description: Setup actionlint +inputs: + version: + description: The version of actionlint + default: 1.6.24 + cache-seed: + required: true + type: string + description: Seed used to invalidate caches + +runs: + using: composite + steps: + + - name: Cache actionlint Binary + uses: actions/cache@v3 + with: + path: /usr/local/bin/actionlint + key: ${{ inputs.cache-seed }}|${{ runner.os }}|${{ runner.arch }}|actionlint|${{ inputs.version }} + + - name: Setup actionlint + shell: bash + run: | + if ! command -v actionlint; then + bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) ${{ inputs.version }} + mv ./actionlint /usr/local/bin/actionlint + fi + - name: Show actionlint Version + shell: bash + run: | + actionlint --version diff --git a/.github/actions/setup-shellcheck/action.yml b/.github/actions/setup-shellcheck/action.yml new file mode 100644 index 0000000..8e3efda --- /dev/null +++ b/.github/actions/setup-shellcheck/action.yml @@ -0,0 +1,35 @@ +--- +name: setup-shellcheck +description: Setup shellcheck +inputs: + version: + description: The version of shellcheck + default: v0.9.0 + cache-seed: + required: true + type: string + description: Seed used to invalidate caches + +runs: + using: composite + steps: + + - name: Cache shellcheck Binary + uses: actions/cache@v3 + with: + path: /usr/local/bin/shellcheck + key: ${{ inputs.cache-seed }}|${{ runner.os }}|${{ runner.arch }}|shellcheck|${{ inputs.version }} + + - name: Setup shellcheck + shell: bash + run: | + if ! command -v shellcheck; then + wget https://github.com/koalaman/shellcheck/releases/download/${{ inputs.version }}/shellcheck-${{ inputs.version }}.${{ runner.os }}.x86_64.tar.xz + tar xf shellcheck-${{ inputs.version }}.${{ runner.os }}.x86_64.tar.xz + mv shellcheck-${{ inputs.version }}/shellcheck /usr/local/bin/shellcheck + rm -rf shellcheck-${{ inputs.version }}.${{ runner.os }}.x86_64.tar.xz shellcheck-${{ inputs.version }} + fi + - name: Show shellcheck Version + shell: bash + run: | + shellcheck --version diff --git a/.github/workflows/.container.template.j2 b/.github/workflows/.container.template.j2 index 68f061c..8234c56 100644 --- a/.github/workflows/.container.template.j2 +++ b/.github/workflows/.container.template.j2 @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/almalinux-containers.yml b/.github/workflows/almalinux-containers.yml index 12dd058..57f7093 100644 --- a/.github/workflows/almalinux-containers.yml +++ b/.github/workflows/almalinux-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/amazonlinux-containers.yml b/.github/workflows/amazonlinux-containers.yml index 311eff4..bc0d3b9 100644 --- a/.github/workflows/amazonlinux-containers.yml +++ b/.github/workflows/amazonlinux-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/archlinux-containers.yml b/.github/workflows/archlinux-containers.yml index 8eb25d3..1917b17 100644 --- a/.github/workflows/archlinux-containers.yml +++ b/.github/workflows/archlinux-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/busybox-containers.yml b/.github/workflows/busybox-containers.yml index 971c86e..689facd 100644 --- a/.github/workflows/busybox-containers.yml +++ b/.github/workflows/busybox-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/centos-containers.yml b/.github/workflows/centos-containers.yml index df7bc36..3c9bd47 100644 --- a/.github/workflows/centos-containers.yml +++ b/.github/workflows/centos-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/centos-stream-containers.yml b/.github/workflows/centos-stream-containers.yml index 7ac077f..822c8d1 100644 --- a/.github/workflows/centos-stream-containers.yml +++ b/.github/workflows/centos-stream-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/consul-containers.yml b/.github/workflows/consul-containers.yml index 2683d31..bafed3d 100644 --- a/.github/workflows/consul-containers.yml +++ b/.github/workflows/consul-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/debian-containers.yml b/.github/workflows/debian-containers.yml index f29af3b..d99e767 100644 --- a/.github/workflows/debian-containers.yml +++ b/.github/workflows/debian-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/etcd-v2-containers.yml b/.github/workflows/etcd-v2-containers.yml index ab8ae6f..84c6981 100644 --- a/.github/workflows/etcd-v2-containers.yml +++ b/.github/workflows/etcd-v2-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/etcd-v3-containers.yml b/.github/workflows/etcd-v3-containers.yml index cd46c23..6c2291d 100644 --- a/.github/workflows/etcd-v3-containers.yml +++ b/.github/workflows/etcd-v3-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/fedora-containers.yml b/.github/workflows/fedora-containers.yml index b135f74..48d7f9d 100644 --- a/.github/workflows/fedora-containers.yml +++ b/.github/workflows/fedora-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/mariadb-containers.yml b/.github/workflows/mariadb-containers.yml index fb3f5c6..37abc2c 100644 --- a/.github/workflows/mariadb-containers.yml +++ b/.github/workflows/mariadb-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/mysql-server-containers.yml b/.github/workflows/mysql-server-containers.yml index f9b7eab..8e2649c 100644 --- a/.github/workflows/mysql-server-containers.yml +++ b/.github/workflows/mysql-server-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/openldap-minion-containers.yml b/.github/workflows/openldap-minion-containers.yml index 17c5fe2..5f24a7f 100644 --- a/.github/workflows/openldap-minion-containers.yml +++ b/.github/workflows/openldap-minion-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/opensuse-containers.yml b/.github/workflows/opensuse-containers.yml index 8225f53..efc62a8 100644 --- a/.github/workflows/opensuse-containers.yml +++ b/.github/workflows/opensuse-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/packaging-containers.yml b/.github/workflows/packaging-containers.yml index 14bb6ed..b015e79 100644 --- a/.github/workflows/packaging-containers.yml +++ b/.github/workflows/packaging-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/percona-containers.yml b/.github/workflows/percona-containers.yml index 9509604..99241fb 100644 --- a/.github/workflows/percona-containers.yml +++ b/.github/workflows/percona-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/photon-containers.yml b/.github/workflows/photon-containers.yml index 8df10ed..6fd4214 100644 --- a/.github/workflows/photon-containers.yml +++ b/.github/workflows/photon-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 943388f..56ca522 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -9,7 +9,13 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + - uses: ./.github/actions/setup-actionlint + with: + cache-seed: ${{ hashFiles('.github/**', 'tools/**') }} + - uses: ./.github/actions/setup-shellcheck + with: + cache-seed: ${{ hashFiles('.github/**', 'tools/**') }} - uses: actions/setup-python@v4 with: python-version: '3.9' diff --git a/.github/workflows/python-containers.yml b/.github/workflows/python-containers.yml index 804345b..e205869 100644 --- a/.github/workflows/python-containers.yml +++ b/.github/workflows/python-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/rabbitmq-containers.yml b/.github/workflows/rabbitmq-containers.yml index 0750dc7..e75c666 100644 --- a/.github/workflows/rabbitmq-containers.yml +++ b/.github/workflows/rabbitmq-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/redis-containers.yml b/.github/workflows/redis-containers.yml index 0fda27b..d9252f5 100644 --- a/.github/workflows/redis-containers.yml +++ b/.github/workflows/redis-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/salt-containers.yml b/.github/workflows/salt-containers.yml index 8840d2d..1bc5c95 100644 --- a/.github/workflows/salt-containers.yml +++ b/.github/workflows/salt-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/salt-gitfs-http-containers.yml b/.github/workflows/salt-gitfs-http-containers.yml index bb1da98..5c5ded2 100644 --- a/.github/workflows/salt-gitfs-http-containers.yml +++ b/.github/workflows/salt-gitfs-http-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/ssh-minion-containers.yml b/.github/workflows/ssh-minion-containers.yml index 642b373..8042af2 100644 --- a/.github/workflows/ssh-minion-containers.yml +++ b/.github/workflows/ssh-minion-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/tinyproxy-containers.yml b/.github/workflows/tinyproxy-containers.yml index 5575ae0..9ad986d 100644 --- a/.github/workflows/tinyproxy-containers.yml +++ b/.github/workflows/tinyproxy-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/ubuntu-containers.yml b/.github/workflows/ubuntu-containers.yml index e1fdb8b..28888a0 100644 --- a/.github/workflows/ubuntu-containers.yml +++ b/.github/workflows/ubuntu-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/vault-containers.yml b/.github/workflows/vault-containers.yml index ef82d71..5b130f4 100644 --- a/.github/workflows/vault-containers.yml +++ b/.github/workflows/vault-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/virt-minion-containers.yml b/.github/workflows/virt-minion-containers.yml index bee258c..d834cb0 100644 --- a/.github/workflows/virt-minion-containers.yml +++ b/.github/workflows/virt-minion-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/zookeeper-containers.yml b/.github/workflows/zookeeper-containers.yml index 2a212aa..1222f05 100644 --- a/.github/workflows/zookeeper-containers.yml +++ b/.github/workflows/zookeeper-containers.yml @@ -28,14 +28,16 @@ concurrency: jobs: matrix-generator: - name: "Mirror Matrix Generator" + name: Generate Matrix runs-on: ubuntu-latest outputs: + tags: ${{ steps.set-matrix.outputs.tags }} + name: ${{ steps.set-matrix.outputs.name }} dockerinfo: ${{ steps.set-matrix.outputs.dockerinfo }} steps: - name: "Throttle Builds" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - name: "Fetching Repository Contents" uses: actions/checkout@v4 @@ -61,10 +63,10 @@ jobs: run: | inv containers.matrix --from-workflow ${{ env.PATH_IN_REPO }} - mirror-image: + build: runs-on: ubuntu-latest needs: matrix-generator - name: "${{ matrix.dockerinfo.name }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" + name: "Build ${{ matrix.dockerinfo.name }}:${{ matrix.dockerinfo.tag }}${{ matrix.dockerinfo.platform && format(' ({0})', matrix.dockerinfo.platform) || ''}}" strategy: fail-fast: false max-parallel: 10 @@ -95,16 +97,18 @@ jobs: - name: "Throttle concurrent pushes" run: | - t=$(shuf -i 5-30 -n 1); echo "Sleeping $t seconds"; sleep $t + t="$(shuf -i 5-30 -n 1)"; echo "Sleeping $t seconds"; sleep "$t" - - name: "Setup DockerFile" - run: | - echo " " >> ./${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.source=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.url=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.documentation=\"https://github.com/${GITHUB_REPOSITORY}/\"" >> ${{matrix.dockerinfo.file}} - echo "LABEL org.opencontainers.image.vendor=\"Unofficial Docker Hub Mirror\"" >> ${{matrix.dockerinfo.file}} - cat ./${{matrix.dockerinfo.file}} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + tags: | + type=raw,value=${{ matrix.dockerinfo.tag }} + flavor: | + latest=false - name: "Docker QEMU" uses: docker/setup-qemu-action@v3 @@ -130,10 +134,94 @@ jobs: - name: "Build & Publish" uses: docker/build-push-action@v5 + id: build with: file: ${{ matrix.dockerinfo.file }} context: ${{ env.PATH_IN_REPO }} platforms: ${{ matrix.dockerinfo.platform }} - push: ${{ github.repository == 'saltstack/salt-ci-containers' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' ) }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }},push-by-digest=true,name-canonical=true,push=${{ + github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + - name: Export digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + run: | + mkdir -p /tmp/digests + touch /tmp/digests/$(echo ${{ steps.build.outputs.digest }} | cut -d ":" -f 2)" + ls -lah /tmp/digests + + - name: Upload digest + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + uses: actions/upload-artifact@v3 + with: + name: digests-${{ matrix.dockerinfo.name }}-${{ matrix.dockerinfo.tag }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + name: "Merge ${{ needs.matrix-generator.outputs.name }}:${{ matrix.tag }}" + if: ${{ github.repository == 'saltstack/salt-ci-containers' && contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) }} + + strategy: + fail-fast: false + max-parallel: 10 + matrix: + tag: ${{ fromJson(needs.matrix-generator.outputs.tags) }} + + needs: + - matrix-generator + - build + + permissions: + actions: read + checks: write + issues: read + packages: write + pull-requests: read + repository-projects: read + statuses: read + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests-${{ needs.matrix-generator.outputs.name }}-${{ matrix.tag }} + path: /tmp/digests + + - name: Show digests + run: | + tree -a /tmp/digests + cat /tmp/digests/* + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }} tags: | - ghcr.io/${{ github.repository }}/${{ matrix.dockerinfo.name }} + type=raw,value=${{ matrix.tag }} + flavor: | + latest=false + + - name: "Log into GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create "$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")" \ + "$(printf 'ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}@sha256:%s ' *)" + + - name: Inspect image + run: | + docker buildx imagetools inspect ghcr.io/${{ github.repository }}/${{ needs.matrix-generator.outputs.name }}:${{ steps.meta.outputs.version }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4f38198..ec1ebc2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,6 +29,19 @@ repos: - msgpack==1.0.3 - six==1.16.0 + - repo: https://github.com/s0undt3ch/python-tools-scripts + rev: "0.18.4" + hooks: + - id: tools + alias: actionlint + name: Lint GitHub Actions Workflows + files: "^.github/workflows/" + types: + - yaml + args: + - pre-commit + - actionlint + - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.3.0 hooks: diff --git a/tasks/containers.py b/tasks/containers.py index 9641a9e..f2eb6d9 100644 --- a/tasks/containers.py +++ b/tasks/containers.py @@ -185,7 +185,9 @@ def matrix(ctx, image, from_workflow=False, build_platforms=None): utils.error(f"Failed to find a container matching path {image}") utils.exit_invoke(1) output = [] + tags = [] for fpath in mirrors_path.glob("*.Dockerfile"): + tags.append(fpath.stem) if "container" in details: source_tag = details.get("source_tag", "{version}").format(version=fpath.stem) source_container = f"{details['container']}:{source_tag}" @@ -204,7 +206,8 @@ def matrix(ctx, image, from_workflow=False, build_platforms=None): continue output.append( { - "name": f"{details['name']}:{fpath.stem}", + "name": details["name"], + "tag": fpath.stem, "platform": platform, "file": str(fpath.relative_to(utils.REPO_ROOT)), "source_container": source_container, @@ -215,7 +218,8 @@ def matrix(ctx, image, from_workflow=False, build_platforms=None): # This is because the buildx inspect did not return anything output.append( { - "name": f"{details['name']}:{fpath.stem}", + "name": details["name"], + "tag": fpath.stem, "file": str(fpath.relative_to(utils.REPO_ROOT)), "source_container": source_container, "platform": "", @@ -232,6 +236,8 @@ def matrix(ctx, image, from_workflow=False, build_platforms=None): utils.exit_invoke(1) with open(github_output, "a", encoding="utf-8") as wfh: wfh.write(f"dockerinfo={json.dumps(output)}\n") + wfh.write(f"tags={json.dumps(tags)}\n") + wfh.write(f"name={details['name']}") @task diff --git a/tools/__init__.py b/tools/__init__.py new file mode 100644 index 0000000..daa4996 --- /dev/null +++ b/tools/__init__.py @@ -0,0 +1,10 @@ +from __future__ import annotations + +import logging + +import ptscripts + +ptscripts.register_tools_module("tools.pre_commit") + +for name in ("boto3", "botocore", "urllib3"): + logging.getLogger(name).setLevel(logging.INFO) diff --git a/tools/pre_commit.py b/tools/pre_commit.py new file mode 100644 index 0000000..307b586 --- /dev/null +++ b/tools/pre_commit.py @@ -0,0 +1,49 @@ +""" +These commands are used by pre-commit. +""" +# pylint: disable=resource-leakage,broad-except,3rd-party-module-not-gated +from __future__ import annotations + +import logging +import shutil + +from ptscripts import command_group +from ptscripts import Context + +log = logging.getLogger(__name__) + +# Define the command group +cgroup = command_group(name="pre-commit", help="Pre-Commit Related Commands", description=__doc__) + + +@cgroup.command( + name="actionlint", + arguments={ + "files": { + "help": "Files to run actionlint against", + "nargs": "*", + }, + "no_color": { + "help": "Disable colors in output", + }, + }, +) +def actionlint(ctx: Context, files: list[str], no_color: bool = False): + """ + Run `actionlint` against workflows. + """ + actionlint = shutil.which("actionlint") + if not actionlint: + ctx.warn("Could not find the 'actionlint' binary") + ctx.exit(0) + cmdline = [actionlint] + if no_color is False: + cmdline.append("-color") + shellcheck = shutil.which("shellcheck") + if shellcheck: + cmdline.append(f"-shellcheck={shellcheck}") + pyflakes = shutil.which("pyflakes") + if pyflakes: + cmdline.append(f"-pyflakes={pyflakes}") + ret = ctx.run(*cmdline, *files, check=False) + ctx.exit(ret.returncode)