Repository navigation
Build and Publish #103
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build and Publish | |
| on: | |
| schedule: | |
| # At 04:00 on day-of-month 1. | |
| - cron: "0 4 1 * *" | |
| workflow_dispatch: | |
| push: | |
| branches: | |
| - "main" | |
| permissions: | |
| contents: write | |
| env: | |
| DOCKERHUB_IMAGE: betterweb/node | |
| FORGEJO_IMAGE: code.bettercorp.dev/bettercorp/docker-node | |
| jobs: | |
| prepare-matrix: | |
| runs-on: blacksmith-2vcpu-ubuntu-2404 | |
| outputs: | |
| matrix: ${{ steps.set-matrix.outputs.matrix }} | |
| latest: ${{ steps.latest-version.outputs.output }} | |
| devcontainer_matrix: ${{ steps.set-dev-matrix.outputs.matrix }} | |
| steps: | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Check Docker image platforms | |
| id: check-platforms | |
| run: | | |
| curl -s "https://nodejs.org/download/release/index.json" >node_versions.json | |
| # Filter out versions older than 2 years | |
| two_years_ago=$(date -u -d "2 years ago" +%s) | |
| jq --argjson two_years_ago "$two_years_ago" '[.[] | select((.date | sub("T.*"; "") | strptime("%Y-%m-%d") | mktime) > $two_years_ago)]' node_versions.json >node_versions_recent.json | |
| # Function to check Docker image platforms | |
| check_platforms() { | |
| version=$1 | |
| # Get platforms from manifest | |
| if manifest=$(docker manifest inspect "node:$version-alpine" 2>/dev/null); then | |
| # Extract all valid platforms (excluding unknown) | |
| platforms=$(echo "$manifest" | jq -r '.manifests[] | | |
| select(.platform.os != "unknown" and .platform.architecture != "unknown") | | |
| if .platform.variant then | |
| "linux/" + .platform.architecture + "/" + .platform.variant | |
| else | |
| "linux/" + .platform.architecture | |
| end' | tr '\n' ',' | sed 's/,$//') | |
| if [ -n "$platforms" ]; then | |
| echo "$platforms" | |
| return | |
| fi | |
| fi | |
| # Default platforms if manifest check fails | |
| echo "linux/amd64,linux/arm64/v8" | |
| } | |
| # Process versions and add platform information (using filtered recent versions) | |
| jq -c '[.[] | select(.version | test("v(1[8-9]|[2-9][0-9]).*"))] | group_by(.version | match("v(\\d+).*").captures[0].string | tonumber) | map(max_by(.version | match("v(\\d+\\.\\d+).*").captures[0].string | split(".") as $parts | ($parts[0] | tonumber) * 1000 + ($parts[1] | tonumber))) | map({version: .version, major: (.version | match("v(\\d+).*").captures[0].string | tonumber)})' node_versions_recent.json >versions.json | |
| # Add platform information to each version | |
| platforms_json="[" | |
| first=true | |
| while IFS= read -r version_info; do | |
| version=$(echo "$version_info" | jq -r '.version') | |
| major=$(echo "$version_info" | jq -r '.major') | |
| version_without_v="${version#v}" # Remove 'v' prefix for Docker tag | |
| platforms=$(check_platforms "$version_without_v") | |
| if [ "$first" = true ]; then | |
| first=false | |
| else | |
| platforms_json="$platforms_json," | |
| fi | |
| platforms_json="$platforms_json{\"version\":\"$version\",\"major\":$major,\"platforms\":\"$platforms\"}" | |
| done < <(jq -c '.[]' versions.json) | |
| platforms_json="$platforms_json]" | |
| echo "$platforms_json" >config.json | |
| - uses: cloudposse/github-action-jq@main | |
| id: latest-version | |
| with: | |
| compact: true | |
| raw-output: true | |
| input: config.json | |
| script: 'sort_by(.major) | reverse | group_by(.major) | map(.[0]) | sort_by(.major) | reverse | .[0].version' | |
| - uses: cloudposse/github-action-jq@main | |
| id: reparse-tags | |
| with: | |
| compact: true | |
| input: config.json | |
| script: '{"tag": . }' | |
| - run: echo 'matrix=${{ steps.reparse-tags.outputs.output }}' >> $GITHUB_OUTPUT | |
| id: set-matrix | |
| # Pick the top 3 major versions for devcontainers | |
| - uses: cloudposse/github-action-jq@main | |
| id: reparse-dev-tags | |
| with: | |
| compact: true | |
| input: config.json | |
| script: 'sort_by(.major) | reverse | group_by(.major) | map(.[0]) | sort_by(.major) | reverse | .[:3] | {"tag": . }' | |
| - run: echo 'matrix=${{ steps.reparse-dev-tags.outputs.output }}' >> $GITHUB_OUTPUT | |
| id: set-dev-matrix | |
| build: | |
| needs: prepare-matrix | |
| runs-on: blacksmith-2vcpu-ubuntu-2404 | |
| strategy: | |
| matrix: ${{fromJson(needs.prepare-matrix.outputs.matrix)}} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v4 | |
| with: | |
| platforms: all | |
| - name: Set up Docker Buildx | |
| id: buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Login to Forgejo | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: code.bettercorp.dev | |
| username: ${{ secrets.BC_CODE_USER }} | |
| password: ${{ secrets.BC_CODE_PACKAGE_TOKEN }} | |
| logout: true | |
| - name: Parse version | |
| id: parse_version | |
| run: | | |
| VERSION=${{ matrix.tag.version }} | |
| PARSED_VERSION=${VERSION#v} | |
| echo "PARSED_VERSION=$PARSED_VERSION" >> $GITHUB_OUTPUT | |
| shell: bash | |
| - name: Is Latest | |
| id: is_latest | |
| run: | | |
| if [ "${{ matrix.tag.version }}" = "${{ needs.prepare-matrix.outputs.latest }}" ]; then | |
| echo "IS_LATEST=true" >> $GITHUB_OUTPUT | |
| echo "This is the latest version" | |
| else | |
| echo "IS_LATEST=false" >> $GITHUB_OUTPUT | |
| echo "This is not the latest version" | |
| fi | |
| - name: Build and push to Forgejo | |
| id: build_image | |
| uses: docker/build-push-action@v7 | |
| with: | |
| build-args: | | |
| NODE_MAJOR=${{ matrix.tag.major }} | |
| NODE_VERSION=${{ steps.parse_version.outputs.PARSED_VERSION }} | |
| context: . | |
| platforms: ${{ matrix.tag.platforms }} | |
| push: true | |
| tags: | | |
| ${{ env.FORGEJO_IMAGE }}:${{steps.parse_version.outputs.PARSED_VERSION}} | |
| ${{ env.FORGEJO_IMAGE }}:${{matrix.tag.major}} | |
| ${{ steps.is_latest.outputs.IS_LATEST == 'true' && format('{0}:latest', env.FORGEJO_IMAGE) || '' }} | |
| - name: Login to DockerHub | |
| continue-on-error: true | |
| uses: docker/login-action@v4 | |
| with: | |
| username: ${{ secrets.DOCKER_HUB_USER }} | |
| password: ${{ secrets.DOCKER_HUB_TOKEN }} | |
| logout: true | |
| - name: Build and push to DockerHub | |
| continue-on-error: true | |
| uses: docker/build-push-action@v7 | |
| with: | |
| build-args: | | |
| NODE_MAJOR=${{ matrix.tag.major }} | |
| NODE_VERSION=${{ steps.parse_version.outputs.PARSED_VERSION }} | |
| context: . | |
| platforms: ${{ matrix.tag.platforms }} | |
| push: true | |
| tags: | | |
| ${{ env.DOCKERHUB_IMAGE }}:${{steps.parse_version.outputs.PARSED_VERSION}} | |
| ${{ env.DOCKERHUB_IMAGE }}:${{matrix.tag.major}} | |
| ${{ steps.is_latest.outputs.IS_LATEST == 'true' && format('{0}:latest', env.DOCKERHUB_IMAGE) || '' }} | |
| - name: Write manifest part | |
| run: | | |
| TAGS=$(jq -nc \ | |
| --arg v "${{ steps.parse_version.outputs.PARSED_VERSION }}" \ | |
| --arg m "${{ matrix.tag.major }}" \ | |
| --arg latest "${{ steps.is_latest.outputs.IS_LATEST }}" \ | |
| --arg dockerhub "${{ env.DOCKERHUB_IMAGE }}" \ | |
| --arg forgejo "${{ env.FORGEJO_IMAGE }}" \ | |
| '[($dockerhub + ":" + $v), ($dockerhub + ":" + $m), ($forgejo + ":" + $v), ($forgejo + ":" + $m)] + (if $latest == "true" then [($dockerhub + ":latest"), ($forgejo + ":latest")] else [] end)') | |
| PLATFORMS=$(echo "${{ matrix.tag.platforms }}" | jq -Rc 'split(",")') | |
| jq -n \ | |
| --arg version "${{ steps.parse_version.outputs.PARSED_VERSION }}" \ | |
| --argjson major ${{ matrix.tag.major }} \ | |
| --arg variant "base" \ | |
| --argjson platforms "$PLATFORMS" \ | |
| --argjson tags "$TAGS" \ | |
| --arg digest "${{ steps.build_image.outputs.digest }}" \ | |
| --argjson is_latest ${{ steps.is_latest.outputs.IS_LATEST }} \ | |
| '{version:$version, major:$major, variant:$variant, platforms:$platforms, tags:$tags, digest:$digest, is_latest:$is_latest}' \ | |
| > part.json | |
| cat part.json | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: manifest-part-base-${{ matrix.tag.major }} | |
| path: part.json | |
| build-dev: | |
| needs: [prepare-matrix, build] | |
| runs-on: blacksmith-2vcpu-ubuntu-2404 | |
| strategy: | |
| matrix: ${{fromJson(needs.prepare-matrix.outputs.devcontainer_matrix)}} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Login to Forgejo | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: code.bettercorp.dev | |
| username: ${{ secrets.BC_CODE_USER }} | |
| password: ${{ secrets.BC_CODE_PACKAGE_TOKEN }} | |
| logout: true | |
| - name: Parse version | |
| id: parse_version | |
| run: | | |
| VERSION=${{ matrix.tag.version }} | |
| PARSED_VERSION=${VERSION#v} | |
| echo "PARSED_VERSION=$PARSED_VERSION" >> $GITHUB_OUTPUT | |
| shell: bash | |
| - name: Is Latest | |
| id: is_latest | |
| run: | | |
| if [ "${{ matrix.tag.version }}" = "${{ needs.prepare-matrix.outputs.latest }}" ]; then | |
| echo "IS_LATEST=true" >> $GITHUB_OUTPUT | |
| echo "This is the latest version" | |
| else | |
| echo "IS_LATEST=false" >> $GITHUB_OUTPUT | |
| echo "This is not the latest version" | |
| fi | |
| - name: Build and push dev image to Forgejo | |
| id: build_image | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| file: Dockerfile.dev | |
| push: true | |
| build-args: | | |
| BASE_IMAGE=${{ env.FORGEJO_IMAGE }} | |
| NODE_MAJOR=${{ matrix.tag.major }} | |
| NODE_VERSION=${{ steps.parse_version.outputs.PARSED_VERSION }} | |
| tags: | | |
| ${{ env.FORGEJO_IMAGE }}:dev-${{steps.parse_version.outputs.PARSED_VERSION}} | |
| ${{ env.FORGEJO_IMAGE }}:dev-${{matrix.tag.major}} | |
| ${{ steps.is_latest.outputs.IS_LATEST == 'true' && format('{0}:dev', env.FORGEJO_IMAGE) || '' }} | |
| - name: Login to DockerHub | |
| continue-on-error: true | |
| uses: docker/login-action@v4 | |
| with: | |
| username: ${{ secrets.DOCKER_HUB_USER }} | |
| password: ${{ secrets.DOCKER_HUB_TOKEN }} | |
| logout: true | |
| - name: Build and push dev image to DockerHub | |
| continue-on-error: true | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| file: Dockerfile.dev | |
| push: true | |
| build-args: | | |
| NODE_MAJOR=${{ matrix.tag.major }} | |
| NODE_VERSION=${{ steps.parse_version.outputs.PARSED_VERSION }} | |
| tags: | | |
| ${{ env.DOCKERHUB_IMAGE }}:dev-${{steps.parse_version.outputs.PARSED_VERSION}} | |
| ${{ env.DOCKERHUB_IMAGE }}:dev-${{matrix.tag.major}} | |
| ${{ steps.is_latest.outputs.IS_LATEST == 'true' && format('{0}:dev', env.DOCKERHUB_IMAGE) || '' }} | |
| - name: Write manifest part | |
| run: | | |
| TAGS=$(jq -nc \ | |
| --arg v "${{ steps.parse_version.outputs.PARSED_VERSION }}" \ | |
| --arg m "${{ matrix.tag.major }}" \ | |
| --arg latest "${{ steps.is_latest.outputs.IS_LATEST }}" \ | |
| --arg dockerhub "${{ env.DOCKERHUB_IMAGE }}" \ | |
| --arg forgejo "${{ env.FORGEJO_IMAGE }}" \ | |
| '[($dockerhub + ":dev-" + $v), ($dockerhub + ":dev-" + $m), ($forgejo + ":dev-" + $v), ($forgejo + ":dev-" + $m)] + (if $latest == "true" then [($dockerhub + ":dev"), ($forgejo + ":dev")] else [] end)') | |
| jq -n \ | |
| --arg version "${{ steps.parse_version.outputs.PARSED_VERSION }}" \ | |
| --argjson major ${{ matrix.tag.major }} \ | |
| --arg variant "dev" \ | |
| --argjson platforms '["linux/amd64"]' \ | |
| --argjson tags "$TAGS" \ | |
| --arg digest "${{ steps.build_image.outputs.digest }}" \ | |
| --argjson is_latest ${{ steps.is_latest.outputs.IS_LATEST }} \ | |
| '{version:$version, major:$major, variant:$variant, platforms:$platforms, tags:$tags, digest:$digest, is_latest:$is_latest}' \ | |
| > part.json | |
| cat part.json | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: manifest-part-dev-${{ matrix.tag.major }} | |
| path: part.json | |
| build-devcontainers: | |
| needs: prepare-matrix | |
| runs-on: blacksmith-2vcpu-ubuntu-2404 | |
| strategy: | |
| matrix: ${{fromJson(needs.prepare-matrix.outputs.devcontainer_matrix)}} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Login to Forgejo | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: code.bettercorp.dev | |
| username: ${{ secrets.BC_CODE_USER }} | |
| password: ${{ secrets.BC_CODE_PACKAGE_TOKEN }} | |
| logout: true | |
| - name: Parse version | |
| id: parse_version | |
| run: | | |
| VERSION=${{ matrix.tag.version }} | |
| PARSED_VERSION=${VERSION#v} | |
| echo "PARSED_VERSION=$PARSED_VERSION" >> $GITHUB_OUTPUT | |
| shell: bash | |
| - name: Is Latest | |
| id: is_latest | |
| run: | | |
| if [ "${{ matrix.tag.version }}" = "${{ needs.prepare-matrix.outputs.latest }}" ]; then | |
| echo "IS_LATEST=true" >> $GITHUB_OUTPUT | |
| echo "This is the latest version" | |
| else | |
| echo "IS_LATEST=false" >> $GITHUB_OUTPUT | |
| echo "This is not the latest version" | |
| fi | |
| - name: Build and push devcontainer image to Forgejo | |
| id: build_image | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| file: Dockerfile.devcontainer | |
| push: true | |
| build-args: | | |
| NODE_MAJOR=${{ matrix.tag.major }} | |
| NODE_VERSION=${{ steps.parse_version.outputs.PARSED_VERSION }} | |
| tags: | | |
| ${{ env.FORGEJO_IMAGE }}:devcontainer-${{steps.parse_version.outputs.PARSED_VERSION}} | |
| ${{ env.FORGEJO_IMAGE }}:devcontainer-${{matrix.tag.major}} | |
| ${{ steps.is_latest.outputs.IS_LATEST == 'true' && format('{0}:devcontainer-latest', env.FORGEJO_IMAGE) || '' }} | |
| - name: Login to DockerHub | |
| continue-on-error: true | |
| uses: docker/login-action@v4 | |
| with: | |
| username: ${{ secrets.DOCKER_HUB_USER }} | |
| password: ${{ secrets.DOCKER_HUB_TOKEN }} | |
| logout: true | |
| - name: Build and push devcontainer image to DockerHub | |
| continue-on-error: true | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| file: Dockerfile.devcontainer | |
| push: true | |
| build-args: | | |
| NODE_MAJOR=${{ matrix.tag.major }} | |
| NODE_VERSION=${{ steps.parse_version.outputs.PARSED_VERSION }} | |
| tags: | | |
| ${{ env.DOCKERHUB_IMAGE }}:devcontainer-${{steps.parse_version.outputs.PARSED_VERSION}} | |
| ${{ env.DOCKERHUB_IMAGE }}:devcontainer-${{matrix.tag.major}} | |
| ${{ steps.is_latest.outputs.IS_LATEST == 'true' && format('{0}:devcontainer-latest', env.DOCKERHUB_IMAGE) || '' }} | |
| - name: Write manifest part | |
| run: | | |
| TAGS=$(jq -nc \ | |
| --arg v "${{ steps.parse_version.outputs.PARSED_VERSION }}" \ | |
| --arg m "${{ matrix.tag.major }}" \ | |
| --arg latest "${{ steps.is_latest.outputs.IS_LATEST }}" \ | |
| --arg dockerhub "${{ env.DOCKERHUB_IMAGE }}" \ | |
| --arg forgejo "${{ env.FORGEJO_IMAGE }}" \ | |
| '[($dockerhub + ":devcontainer-" + $v), ($dockerhub + ":devcontainer-" + $m), ($forgejo + ":devcontainer-" + $v), ($forgejo + ":devcontainer-" + $m)] + (if $latest == "true" then [($dockerhub + ":devcontainer-latest"), ($forgejo + ":devcontainer-latest")] else [] end)') | |
| jq -n \ | |
| --arg version "${{ steps.parse_version.outputs.PARSED_VERSION }}" \ | |
| --argjson major ${{ matrix.tag.major }} \ | |
| --arg variant "devcontainer" \ | |
| --argjson platforms '["linux/amd64"]' \ | |
| --argjson tags "$TAGS" \ | |
| --arg digest "${{ steps.build_image.outputs.digest }}" \ | |
| --argjson is_latest ${{ steps.is_latest.outputs.IS_LATEST }} \ | |
| '{version:$version, major:$major, variant:$variant, platforms:$platforms, tags:$tags, digest:$digest, is_latest:$is_latest}' \ | |
| > part.json | |
| cat part.json | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: manifest-part-devcontainer-${{ matrix.tag.major }} | |
| path: part.json | |
| build-dind: | |
| needs: [prepare-matrix, build] | |
| runs-on: blacksmith-2vcpu-ubuntu-2404 | |
| strategy: | |
| matrix: ${{fromJson(needs.prepare-matrix.outputs.devcontainer_matrix)}} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Login to Forgejo | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: code.bettercorp.dev | |
| username: ${{ secrets.BC_CODE_USER }} | |
| password: ${{ secrets.BC_CODE_PACKAGE_TOKEN }} | |
| logout: true | |
| - name: Parse version | |
| id: parse_version | |
| run: | | |
| VERSION=${{ matrix.tag.version }} | |
| PARSED_VERSION=${VERSION#v} | |
| echo "PARSED_VERSION=$PARSED_VERSION" >> $GITHUB_OUTPUT | |
| shell: bash | |
| - name: Is Latest | |
| id: is_latest | |
| run: | | |
| if [ "${{ matrix.tag.version }}" = "${{ needs.prepare-matrix.outputs.latest }}" ]; then | |
| echo "IS_LATEST=true" >> $GITHUB_OUTPUT | |
| echo "This is the latest version" | |
| else | |
| echo "IS_LATEST=false" >> $GITHUB_OUTPUT | |
| echo "This is not the latest version" | |
| fi | |
| - name: Build and push dind image to Forgejo | |
| id: build_image | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| file: Dockerfile.dind | |
| push: true | |
| build-args: | | |
| BASE_IMAGE=${{ env.FORGEJO_IMAGE }} | |
| NODE_MAJOR=${{ matrix.tag.major }} | |
| NODE_VERSION=${{ steps.parse_version.outputs.PARSED_VERSION }} | |
| tags: | | |
| ${{ env.FORGEJO_IMAGE }}:dind-${{steps.parse_version.outputs.PARSED_VERSION}} | |
| ${{ env.FORGEJO_IMAGE }}:dind-${{matrix.tag.major}} | |
| ${{ steps.is_latest.outputs.IS_LATEST == 'true' && format('{0}:dind-latest', env.FORGEJO_IMAGE) || '' }} | |
| - name: Login to DockerHub | |
| continue-on-error: true | |
| uses: docker/login-action@v4 | |
| with: | |
| username: ${{ secrets.DOCKER_HUB_USER }} | |
| password: ${{ secrets.DOCKER_HUB_TOKEN }} | |
| logout: true | |
| - name: Build and push dind image to DockerHub | |
| continue-on-error: true | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| file: Dockerfile.dind | |
| push: true | |
| build-args: | | |
| NODE_MAJOR=${{ matrix.tag.major }} | |
| NODE_VERSION=${{ steps.parse_version.outputs.PARSED_VERSION }} | |
| tags: | | |
| ${{ env.DOCKERHUB_IMAGE }}:dind-${{steps.parse_version.outputs.PARSED_VERSION}} | |
| ${{ env.DOCKERHUB_IMAGE }}:dind-${{matrix.tag.major}} | |
| ${{ steps.is_latest.outputs.IS_LATEST == 'true' && format('{0}:dind-latest', env.DOCKERHUB_IMAGE) || '' }} | |
| - name: Write manifest part | |
| run: | | |
| TAGS=$(jq -nc \ | |
| --arg v "${{ steps.parse_version.outputs.PARSED_VERSION }}" \ | |
| --arg m "${{ matrix.tag.major }}" \ | |
| --arg latest "${{ steps.is_latest.outputs.IS_LATEST }}" \ | |
| --arg dockerhub "${{ env.DOCKERHUB_IMAGE }}" \ | |
| --arg forgejo "${{ env.FORGEJO_IMAGE }}" \ | |
| '[($dockerhub + ":dind-" + $v), ($dockerhub + ":dind-" + $m), ($forgejo + ":dind-" + $v), ($forgejo + ":dind-" + $m)] + (if $latest == "true" then [($dockerhub + ":dind-latest"), ($forgejo + ":dind-latest")] else [] end)') | |
| jq -n \ | |
| --arg version "${{ steps.parse_version.outputs.PARSED_VERSION }}" \ | |
| --argjson major ${{ matrix.tag.major }} \ | |
| --arg variant "dind" \ | |
| --argjson platforms '["linux/amd64"]' \ | |
| --argjson tags "$TAGS" \ | |
| --arg digest "${{ steps.build_image.outputs.digest }}" \ | |
| --argjson is_latest ${{ steps.is_latest.outputs.IS_LATEST }} \ | |
| '{version:$version, major:$major, variant:$variant, platforms:$platforms, tags:$tags, digest:$digest, is_latest:$is_latest}' \ | |
| > part.json | |
| cat part.json | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: manifest-part-dind-${{ matrix.tag.major }} | |
| path: part.json | |
| publish-manifest: | |
| needs: [prepare-matrix, build, build-dev, build-devcontainers, build-dind] | |
| runs-on: blacksmith-2vcpu-ubuntu-2404 | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: manifest-part-* | |
| merge-multiple: true | |
| path: parts/ | |
| - name: Merge manifest parts | |
| run: | | |
| TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ) | |
| LATEST_VERSION="${{ needs.prepare-matrix.outputs.latest }}" | |
| LATEST_VERSION_STRIPPED="${LATEST_VERSION#v}" | |
| jq -s \ | |
| --arg ts "$TIMESTAMP" \ | |
| --arg latest "$LATEST_VERSION_STRIPPED" \ | |
| --arg run_id "${{ github.run_id }}" \ | |
| --arg run_number "${{ github.run_number }}" \ | |
| --arg sha "${{ github.sha }}" \ | |
| '{ | |
| build: { | |
| run_id: ($run_id | tonumber), | |
| run_number: ($run_number | tonumber), | |
| sha: $sha, | |
| timestamp: $ts | |
| }, | |
| latest: $latest, | |
| builds: ( | |
| group_by(.version) | |
| | map({ | |
| version: .[0].version, | |
| major: .[0].major, | |
| is_latest: .[0].is_latest, | |
| platforms: (map(.platforms) | add | unique), | |
| variants: ( | |
| map({(.variant): {tags: .tags, platforms: .platforms, digest: .digest}}) | add | |
| ) | |
| }) | |
| | sort_by(.major) | reverse | |
| ) | |
| }' parts/*.json > manifest.json | |
| cat manifest.json | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: manifest | |
| path: manifest.json | |
| - name: Create release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| TAG="build-${{ github.run_number }}" | |
| TITLE="Build #${{ github.run_number }} — node ${{ needs.prepare-matrix.outputs.latest }}" | |
| # Drop existing release+tag if re-running the same workflow. | |
| gh release delete "$TAG" -y --cleanup-tag --repo "${{ github.repository }}" 2>/dev/null || true | |
| gh release create "$TAG" \ | |
| --repo "${{ github.repository }}" \ | |
| --title "$TITLE" \ | |
| --notes "Auto-generated manifest of betterweb/node multi-arch builds. Fetch latest via: https://github.com/${{ github.repository }}/releases/latest/download/manifest.json" \ | |
| --latest \ | |
| manifest.json |