From 2399362f0285bbbded504d7c9c49391b4b833eb4 Mon Sep 17 00:00:00 2001 From: Ralf Pannemans Date: Mon, 17 Mar 2025 16:12:15 +0100 Subject: [PATCH 1/3] Add ARM dependencies --- buildpack.toml | 104 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/buildpack.toml b/buildpack.toml index b2e3a330..9bf4473a 100644 --- a/buildpack.toml +++ b/buildpack.toml @@ -28,9 +28,26 @@ api = "0.7" source-checksum = "sha256:abf47264a9a13b2233743ce8a966945388a1a10a56f841310a6d4dd12e18ca9a" stacks = ["io.buildpacks.stacks.jammy", "*"] strip-components = 1 + arch = "amd64" uri = "https://nodejs.org/dist/v18.20.6/node-v18.20.6-linux-x64.tar.xz" version = "18.20.6" + [[metadata.dependencies]] + checksum = "sha256:169d317cc39ba5513c9588f7aded1bdff7f807b82c4dacb40ca03fd427d288b0" + cpe = "cpe:2.3:a:nodejs:node.js:18.20.6:*:*:*:*:*:*:*" + deprecation_date = "2025-04-30T00:00:00Z" + id = "node" + licenses = ["0BSD", "Apache-2.0", "Artistic-2.0", "BSD-2-Clause", "BSD-3-Clause", "BSD-4-Clause", "BSD-Source-Code", "CC0-1.0", "ECL-2.0", "ICU", "MIT", "MIT-0", "SHL-0.5", "SHL-0.51", "Unicode-TOU"] + name = "Node Engine" + purl = "pkg:generic/node@v18.20.6?checksum=169d317cc39ba5513c9588f7aded1bdff7f807b82c4dacb40ca03fd427d288b0&download_url=https://nodejs.org/dist/v18.20.6/node-v18.20.6-linux-arm64.tar.xz" + source = "https://nodejs.org/dist/v18.20.6/node-v18.20.6-linux-arm64.tar.xz" + source-checksum = "sha256:169d317cc39ba5513c9588f7aded1bdff7f807b82c4dacb40ca03fd427d288b0" + stacks = ["io.buildpacks.stacks.jammy", "*"] + strip-components = 1 + arch = "arm64" + uri = "https://nodejs.org/dist/v18.20.6/node-v18.20.6-linux-arm64.tar.xz" + version = "18.20.6" + [[metadata.dependencies]] checksum = "sha256:deaf9695966087815a09c1c8e7fb0cfeb5b5b4471836e5993431230a845becad" cpe = "cpe:2.3:a:nodejs:node.js:18.20.7:*:*:*:*:*:*:*" @@ -43,11 +60,28 @@ api = "0.7" source-checksum = "sha256:deaf9695966087815a09c1c8e7fb0cfeb5b5b4471836e5993431230a845becad" stacks = ["io.buildpacks.stacks.jammy", "*"] strip-components = 1 + arch = "amd64" uri = "https://nodejs.org/dist/v18.20.7/node-v18.20.7-linux-x64.tar.xz" version = "18.20.7" [[metadata.dependencies]] - checksum = "sha256:4e50f727ae09bdafecf2322c72faf7cd82bf3b8851a16b8bb63974e0d8d6eceb" + checksum = "sha256:c788ad58ded0426a7fca9f3a7e005f57c14a348ebdb3a2977e19ef7b0c143439" + cpe = "cpe:2.3:a:nodejs:node.js:18.20.7:*:*:*:*:*:*:*" + deprecation_date = "2025-04-30T00:00:00Z" + id = "node" + licenses = ["0BSD", "Apache-2.0", "Artistic-2.0", "BSD-2-Clause", "BSD-3-Clause", "BSD-4-Clause", "BSD-Source-Code", "CC0-1.0", "ECL-2.0", "ICU", "MIT", "MIT-0", "SHL-0.5", "SHL-0.51", "Unicode-TOU"] + name = "Node Engine" + purl = "pkg:generic/node@v18.20.7?checksum=c788ad58ded0426a7fca9f3a7e005f57c14a348ebdb3a2977e19ef7b0c143439&download_url=https://nodejs.org/dist/v18.20.7/node-v18.20.7-linux-arm64.tar.xz" + source = "https://nodejs.org/dist/v18.20.7/node-v18.20.7-linux-arm64.tar.xz" + source-checksum = "sha256:c788ad58ded0426a7fca9f3a7e005f57c14a348ebdb3a2977e19ef7b0c143439" + stacks = ["io.buildpacks.stacks.jammy", "*"] + strip-components = 1 + arch = "arm64" + uri = "https://nodejs.org/dist/v18.20.7/node-v18.20.7-linux-arm64.tar.xz" + version = "18.20.7" + + [[metadata.dependencies]] + checksum = "sha256:4543670b589593f8fa5f106111fd5139081da42bb165a9239f05195e405f240a" cpe = "cpe:2.3:a:nodejs:node.js:20.18.2:*:*:*:*:*:*:*" deprecation_date = "2026-04-30T00:00:00Z" id = "node" @@ -58,9 +92,26 @@ api = "0.7" source-checksum = "sha256:4e50f727ae09bdafecf2322c72faf7cd82bf3b8851a16b8bb63974e0d8d6eceb" stacks = ["io.buildpacks.stacks.jammy", "*"] strip-components = 1 + arch = "amd64" uri = "https://nodejs.org/dist/v20.18.2/node-v20.18.2-linux-x64.tar.xz" version = "20.18.2" + [[metadata.dependencies]] + checksum = "sha256:5c1437aa16e7e6a2e0687a42c4d3f0a8f8a2039cda8880cb3be8cd983aeefb44" + cpe = "cpe:2.3:a:nodejs:node.js:20.18.2:*:*:*:*:*:*:*" + deprecation_date = "2026-04-30T00:00:00Z" + id = "node" + licenses = ["0BSD", "Apache-2.0", "Artistic-2.0", "BSD-2-Clause", "BSD-3-Clause", "BSD-4-Clause", "BSD-Source-Code", "CC0-1.0", "ECL-2.0", "ICU", "MIT", "MIT-0", "SHL-0.5", "SHL-0.51", "Unicode-TOU"] + name = "Node Engine" + purl = "pkg:generic/node@v20.18.2?checksum=5c1437aa16e7e6a2e0687a42c4d3f0a8f8a2039cda8880cb3be8cd983aeefb44&download_url=https://nodejs.org/dist/v20.18.2/node-v20.18.2-linux-arm64.tar.xz" + source = "https://nodejs.org/dist/v20.18.2/node-v20.18.2-linux-arm64.tar.xz" + source-checksum = "sha256:5c1437aa16e7e6a2e0687a42c4d3f0a8f8a2039cda8880cb3be8cd983aeefb44" + stacks = ["io.buildpacks.stacks.jammy", "*"] + strip-components = 1 + arch = "arm64" + uri = "https://nodejs.org/dist/v20.18.2/node-v20.18.2-linux-arm64.tar.xz" + version = "20.18.2" + [[metadata.dependencies]] checksum = "sha256:595bcc9a28e6d1ee5fc7277b5c3cb029275b98ec0524e162a0c566c992a7ee5c" cpe = "cpe:2.3:a:nodejs:node.js:20.18.3:*:*:*:*:*:*:*" @@ -73,9 +124,26 @@ api = "0.7" source-checksum = "sha256:595bcc9a28e6d1ee5fc7277b5c3cb029275b98ec0524e162a0c566c992a7ee5c" stacks = ["io.buildpacks.stacks.jammy", "*"] strip-components = 1 + arch = "amd64" uri = "https://nodejs.org/dist/v20.18.3/node-v20.18.3-linux-x64.tar.xz" version = "20.18.3" + [[metadata.dependencies]] + checksum = "sha256:c03412ab9c0ed30468e4d03e56d2e35c5ae761a98deb16727c7af2fe5be34700" + cpe = "cpe:2.3:a:nodejs:node.js:20.18.3:*:*:*:*:*:*:*" + deprecation_date = "2026-04-30T00:00:00Z" + id = "node" + licenses = ["0BSD", "Apache-2.0", "Artistic-2.0", "BSD-2-Clause", "BSD-3-Clause", "BSD-4-Clause", "BSD-Source-Code", "CC0-1.0", "ECL-2.0", "ICU", "MIT", "MIT-0", "SHL-0.5", "SHL-0.51", "Unicode-TOU"] + name = "Node Engine" + purl = "pkg:generic/node@v20.18.3?checksum=c03412ab9c0ed30468e4d03e56d2e35c5ae761a98deb16727c7af2fe5be34700&download_url=https://nodejs.org/dist/v20.18.3/node-v20.18.3-linux-arm64.tar.xz" + source = "https://nodejs.org/dist/v20.18.3/node-v20.18.3-linux-arm64.tar.xz" + source-checksum = "sha256:c03412ab9c0ed30468e4d03e56d2e35c5ae761a98deb16727c7af2fe5be34700" + stacks = ["io.buildpacks.stacks.jammy", "*"] + strip-components = 1 + arch = "arm64" + uri = "https://nodejs.org/dist/v20.18.3/node-v20.18.3-linux-arm64.tar.xz" + version = "20.18.3" + [[metadata.dependencies]] checksum = "sha256:0d2a5af33c7deab5555c8309cd3f373446fe1526c1b95833935ab3f019733b3b" cpe = "cpe:2.3:a:nodejs:node.js:22.13.1:*:*:*:*:*:*:*" @@ -88,9 +156,26 @@ api = "0.7" source-checksum = "sha256:0d2a5af33c7deab5555c8309cd3f373446fe1526c1b95833935ab3f019733b3b" stacks = ["io.buildpacks.stacks.jammy", "*"] strip-components = 1 + arch = "amd64" uri = "https://nodejs.org/dist/v22.13.1/node-v22.13.1-linux-x64.tar.xz" version = "22.13.1" + [[metadata.dependencies]] + checksum = "sha256:0a237c413ccbab920640438bf6e1a32edb19845bdc21f0e1cd5b91545ce1c126" + cpe = "cpe:2.3:a:nodejs:node.js:22.13.1:*:*:*:*:*:*:*" + deprecation_date = "2027-04-30T00:00:00Z" + id = "node" + licenses = ["0BSD", "Apache-2.0", "Artistic-2.0", "BSD-2-Clause", "BSD-3-Clause", "BSD-4-Clause", "BSD-Source-Code", "CC0-1.0", "ECL-2.0", "ICU", "MIT", "MIT-0", "SHL-0.5", "SHL-0.51", "Unicode-TOU"] + name = "Node Engine" + purl = "pkg:generic/node@v22.13.1?checksum=0a237c413ccbab920640438bf6e1a32edb19845bdc21f0e1cd5b91545ce1c126&download_url=https://nodejs.org/dist/v22.13.1/node-v22.13.1-linux-arm64.tar.xz" + source = "https://nodejs.org/dist/v22.13.1/node-v22.13.1-linux-arm64.tar.xz" + source-checksum = "sha256:0a237c413ccbab920640438bf6e1a32edb19845bdc21f0e1cd5b91545ce1c126" + stacks = ["io.buildpacks.stacks.jammy", "*"] + strip-components = 1 + arch = "arm64" + uri = "https://nodejs.org/dist/v22.13.1/node-v22.13.1-linux-arm64.tar.xz" + version = "22.13.1" + [[metadata.dependencies]] checksum = "sha256:69b09dba5c8dcb05c4e4273a4340db1005abeafe3927efda2bc5b249e80437ec" cpe = "cpe:2.3:a:nodejs:node.js:22.14.0:*:*:*:*:*:*:*" @@ -103,9 +188,26 @@ api = "0.7" source-checksum = "sha256:69b09dba5c8dcb05c4e4273a4340db1005abeafe3927efda2bc5b249e80437ec" stacks = ["io.buildpacks.stacks.jammy", "*"] strip-components = 1 + arch = "amd64" uri = "https://nodejs.org/dist/v22.14.0/node-v22.14.0-linux-x64.tar.xz" version = "22.14.0" + [[metadata.dependencies]] + checksum = "sha256:08bfbf538bad0e8cbb0269f0173cca28d705874a67a22f60b57d99dc99e30050" + cpe = "cpe:2.3:a:nodejs:node.js:22.14.0:*:*:*:*:*:*:*" + deprecation_date = "2027-04-30T00:00:00Z" + id = "node" + licenses = ["0BSD", "Apache-2.0", "Artistic-2.0", "BSD-2-Clause", "BSD-3-Clause", "BSD-4-Clause", "BSD-Source-Code", "CC0-1.0", "ECL-2.0", "ICU", "MIT", "MIT-0", "SHL-0.5", "SHL-0.51", "Unicode-TOU"] + name = "Node Engine" + purl = "pkg:generic/node@v22.14.0?checksum=08bfbf538bad0e8cbb0269f0173cca28d705874a67a22f60b57d99dc99e30050&download_url=https://nodejs.org/dist/v22.14.0/node-v22.14.0-linux-arm64.tar.xz" + source = "https://nodejs.org/dist/v22.14.0/node-v22.14.0-linux-arm64.tar.xz" + source-checksum = "sha256:08bfbf538bad0e8cbb0269f0173cca28d705874a67a22f60b57d99dc99e30050" + stacks = ["io.buildpacks.stacks.jammy", "*"] + strip-components = 1 + arch = "arm64" + uri = "https://nodejs.org/dist/v22.14.0/node-v22.14.0-linux-arm64.tar.xz" + version = "22.14.0" + [[metadata.dependency-constraints]] constraint = "18.*" id = "node" From 93da5f2f153774089bc3d9932250b8ba8b1b58ff Mon Sep 17 00:00:00 2001 From: Ralf Pannemans Date: Fri, 28 Mar 2025 11:27:30 +0100 Subject: [PATCH 2/3] Add multiarch changes from npm-install --- .github/.syncignore | 2 + .github/workflows/create-draft-release.yml | 95 ++++++++++++--- .github/workflows/push-buildpackage.yml | 112 ++++++++++++------ .gitignore | 5 +- buildpack.toml | 26 ++++- scripts/build.sh | 105 +++++++++++------ scripts/package.sh | 29 ++--- scripts/publish.sh | 129 +++++++++++++++++++++ 8 files changed, 394 insertions(+), 109 deletions(-) create mode 100755 scripts/publish.sh diff --git a/.github/.syncignore b/.github/.syncignore index b82bab24..cc55ec51 100644 --- a/.github/.syncignore +++ b/.github/.syncignore @@ -1,2 +1,4 @@ CODEOWNERS workflows/update-dependencies.yml +workflows/push-buildpackage.yml +workflows/create-draft-release.yml \ No newline at end of file diff --git a/.github/workflows/create-draft-release.yml b/.github/workflows/create-draft-release.yml index acc723ec..8b025a42 100644 --- a/.github/workflows/create-draft-release.yml +++ b/.github/workflows/create-draft-release.yml @@ -61,6 +61,12 @@ jobs: name: Release runs-on: ubuntu-22.04 needs: integration + services: + registry: + image: registry:2 + ports: + - 5000:5000 + steps: - name: Setup Go uses: actions/setup-go@v3 @@ -110,6 +116,16 @@ jobs: echo "buildpack_type=buildpack" >> "$GITHUB_OUTPUT" fi + - name: Get buildpack path + id: get_buildpack_path + run: | + + if [ -f "build/buildpackage.cnb" ]; then + echo "path=build/buildpackage.cnb" >> "$GITHUB_OUTPUT" + else + echo "path=build/buildpackage-linux-amd64.cnb" >> "$GITHUB_OUTPUT" + fi + - name: Create Release Notes id: create-release-notes uses: paketo-buildpacks/github-config/actions/release/notes@main @@ -117,6 +133,69 @@ jobs: repo: ${{ github.repository }} token: ${{ secrets.PAKETO_BOT_GITHUB_TOKEN }} buildpack_type: ${{ steps.get_buildpack_type.outputs.buildpack_type }} + buildpackage_path: ${{ steps.get_buildpack_path.outputs.path }} + + - name: Get Image Digest + id: image_digest + run: | + image_name="localhost:5000/npm-install:latest" + + ./scripts/publish.sh \ + --buildpack-archive ./build/buildpack.tgz \ + --image-ref $image_name + + echo "digest=$(sudo skopeo inspect "docker://${image_name}" --tls-verify=false | jq -r .Digest)" >> "$GITHUB_OUTPUT" + + - name: Set Correct Image Digest on the Release notes + run: | + printf '${{ steps.create-release-notes.outputs.release_body }}' \ + | sed -E \ + "s/\*\*Digest:\*\* \`sha256:[a-f0-9]{64}\`/\*\*Digest:\*\* \`${{ steps.image_digest.outputs.digest }}\`/" \ + > ./release_notes + + printf '${{ steps.image_digest.outputs.digest }}' > ./index-digest.sha256 + + - name: Create release assets + id: create_release_assets + run: | + release_assets=$(jq -n --arg repo_name "${{ github.event.repository.name }}" --arg tag "${{ steps.tag.outputs.tag }}" ' + [ + { + "path": "build/buildpack.tgz", + "name": ($repo_name + "-" + $tag + ".tgz"), + "content_type": "application/gzip" + }, + { + "path": "./index-digest.sha256", + "name": ($repo_name + "-" + $tag + "-" + "index-digest.sha256"), + "content_type": "text/plain" + } + ]') + + for filepath in build/*.cnb; do + filename=$(basename "$filepath") + asset_name="" + if [[ "$filename" == "buildpackage-linux-amd64.cnb" ]]; then + asset_name="${{ github.event.repository.name }}-${{ steps.tag.outputs.tag }}.cnb" + elif [[ "$filename" == "buildpackage.cnb" ]]; then + asset_name="${{ github.event.repository.name }}-${{ steps.tag.outputs.tag }}.cnb" + else + formatted_filename="${filename#buildpackage-}" + asset_name="${{ github.event.repository.name }}-${{ steps.tag.outputs.tag }}-${formatted_filename}" + fi + + release_assets=$(echo "$release_assets" | jq --arg asset_name "${asset_name}" --arg filepath "$filepath" ' + . + [ + { + "path": $filepath, + "name": $asset_name, + "content_type": "application/gzip" + } + ]') + done + + release_assets=$(jq -c <<< "$release_assets" ) + printf "release_assets=%s\n" "${release_assets}" >> "$GITHUB_OUTPUT" - name: Create Release uses: paketo-buildpacks/github-config/actions/release/create@main @@ -126,21 +205,9 @@ jobs: tag_name: v${{ steps.tag.outputs.tag }} target_commitish: ${{ github.sha }} name: v${{ steps.tag.outputs.tag }} - body: ${{ steps.create-release-notes.outputs.release_body }} + body_filepath: "./release_notes" draft: true - assets: | - [ - { - "path": "build/buildpack.tgz", - "name": "${{ github.event.repository.name }}-${{ steps.tag.outputs.tag }}.tgz", - "content_type": "application/gzip" - }, - { - "path": "build/buildpackage.cnb", - "name": "${{ github.event.repository.name }}-${{ steps.tag.outputs.tag }}.cnb", - "content_type": "application/gzip" - } - ] + assets: ${{ steps.create_release_assets.outputs.release_assets }} failure: name: Alert on Failure diff --git a/.github/workflows/push-buildpackage.yml b/.github/workflows/push-buildpackage.yml index 390ce277..2fca2b34 100644 --- a/.github/workflows/push-buildpackage.yml +++ b/.github/workflows/push-buildpackage.yml @@ -4,13 +4,22 @@ on: release: types: - published + env: REGISTRIES_FILENAME: "registries.json" jobs: push: name: Push - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 + env: + GCR_REGISTRY: "gcr.io" + GCR_PASSWORD: ${{ secrets.GCR_PUSH_BOT_JSON_KEY }} + GCR_USERNAME: "_json_key" + DOCKERHUB_REGISTRY: docker.io + DOCKERHUB_USERNAME: ${{ secrets.PAKETO_BUILDPACKS_DOCKERHUB_USERNAME }} + DOCKERHUB_PASSWORD: ${{ secrets.PAKETO_BUILDPACKS_DOCKERHUB_PASSWORD }} + steps: - name: Checkout @@ -25,30 +34,40 @@ jobs: echo "tag_full=${FULL_VERSION}" >> "$GITHUB_OUTPUT" echo "tag_minor=${MINOR_VERSION}" >> "$GITHUB_OUTPUT" echo "tag_major=${MAJOR_VERSION}" >> "$GITHUB_OUTPUT" - echo "download_url=$(jq -r '.release.assets[] | select(.name | endswith(".cnb")) | .url' "${GITHUB_EVENT_PATH}")" >> "$GITHUB_OUTPUT" + echo "download_tgz_file_url=$(jq -r '.release.assets[] | select(.name | endswith(".tgz")) | .url' "${GITHUB_EVENT_PATH}")" >> "$GITHUB_OUTPUT" + echo "download_cnb_file_url=$(jq -r --arg tag_full "$FULL_VERSION" '.release.assets[] | select(.name | endswith($tag_full + ".cnb")) | .url' "${GITHUB_EVENT_PATH}")" >> "$GITHUB_OUTPUT" + echo "download_sha256_file_url=$(jq -r '.release.assets[] | select(.name | endswith("index-digest.sha256")) | .url' "${GITHUB_EVENT_PATH}")" >> "$GITHUB_OUTPUT" - - name: Download - id: download + - name: Download .cnb buildpack uses: paketo-buildpacks/github-config/actions/release/download-asset@main with: - url: ${{ steps.event.outputs.download_url }} + url: ${{ steps.event.outputs.download_cnb_file_url }} output: "/github/workspace/buildpackage.cnb" token: ${{ secrets.PAKETO_BOT_GITHUB_TOKEN }} + - name: Download .tgz buildpack + uses: paketo-buildpacks/github-config/actions/release/download-asset@main + with: + url: ${{ steps.event.outputs.download_tgz_file_url }} + output: "/github/workspace/buildpack.tgz" + token: ${{ secrets.PAKETO_BOT_GITHUB_TOKEN }} + + - name: Download .sha digest + uses: paketo-buildpacks/github-config/actions/release/download-asset@main + with: + url: ${{ steps.event.outputs.download_sha256_file_url }} + output: "/github/workspace/index-digest.sha256" + token: ${{ secrets.PAKETO_BOT_GITHUB_TOKEN }} + - name: Parse Configs id: parse_configs run: | - registries_filename="${{ env.REGISTRIES_FILENAME }}" - push_to_dockerhub=true - push_to_gcr=true + push_to_gcr=false - if [[ -f $registries_filename ]]; then - if jq 'has("dockerhub")' $registries_filename > /dev/null; then - push_to_dockerhub=$(jq '.dockerhub' $registries_filename) - fi - if jq 'has("GCR")' $registries_filename > /dev/null; then - push_to_gcr=$(jq '.GCR' $registries_filename) + if [[ -f $REGISTRIES_FILENAME ]]; then + if jq 'has("dockerhub")' $REGISTRIES_FILENAME > /dev/null; then + push_to_dockerhub=$(jq '.dockerhub' $REGISTRIES_FILENAME) fi fi @@ -64,41 +83,64 @@ jobs: exit 1 fi - - name: Push to GCR - if: ${{ steps.parse_configs.outputs.push_to_gcr == 'true' }} - env: - GCR_PUSH_BOT_JSON_KEY: ${{ secrets.GCR_PUSH_BOT_JSON_KEY }} - run: | - echo "${GCR_PUSH_BOT_JSON_KEY}" | sudo skopeo login --username _json_key --password-stdin gcr.io - sudo skopeo copy "oci-archive:${GITHUB_WORKSPACE}/buildpackage.cnb" "docker://gcr.io/${{ github.repository }}:${{ steps.event.outputs.tag_full }}" - sudo skopeo copy "oci-archive:${GITHUB_WORKSPACE}/buildpackage.cnb" "docker://gcr.io/${{ github.repository }}:${{ steps.event.outputs.tag_minor }}" - sudo skopeo copy "oci-archive:${GITHUB_WORKSPACE}/buildpackage.cnb" "docker://gcr.io/${{ github.repository }}:${{ steps.event.outputs.tag_major }}" - sudo skopeo copy "oci-archive:${GITHUB_WORKSPACE}/buildpackage.cnb" "docker://gcr.io/${{ github.repository }}:latest" + - name: Docker login docker.io + uses: docker/login-action@v3 + with: + username: ${{ env.DOCKERHUB_USERNAME }} + password: ${{ env.DOCKERHUB_PASSWORD }} + registry: ${{ env.DOCKERHUB_REGISTRY }} + + - name: Docker login gcr.io + uses: docker/login-action@v3 + if: ${{ steps.parse_configs.outputs.push_to_gcr == 'true' }} + with: + username: ${{ env.GCR_USERNAME }} + password: ${{ env.GCR_PASSWORD }} + registry: ${{ env.GCR_REGISTRY }} - name: Push to DockerHub if: ${{ steps.parse_configs.outputs.push_to_dockerhub == 'true' }} id: push env: - DOCKERHUB_USERNAME: ${{ secrets.PAKETO_BUILDPACKS_DOCKERHUB_USERNAME }} - DOCKERHUB_PASSWORD: ${{ secrets.PAKETO_BUILDPACKS_DOCKERHUB_PASSWORD }} GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }} run: | - REPOSITORY="${GITHUB_REPOSITORY_OWNER/-/}/${GITHUB_REPOSITORY#${GITHUB_REPOSITORY_OWNER}/}" # translates 'paketo-buildpacks/bundle-install' to 'paketobuildpacks/bundle-install' - IMAGE="index.docker.io/${REPOSITORY}" - echo "${DOCKERHUB_PASSWORD}" | sudo skopeo login --username "${DOCKERHUB_USERNAME}" --password-stdin index.docker.io - sudo skopeo copy "oci-archive:${GITHUB_WORKSPACE}/buildpackage.cnb" "docker://${IMAGE}:${{ steps.event.outputs.tag_full }}" - sudo skopeo copy "oci-archive:${GITHUB_WORKSPACE}/buildpackage.cnb" "docker://${IMAGE}:${{ steps.event.outputs.tag_minor }}" - sudo skopeo copy "oci-archive:${GITHUB_WORKSPACE}/buildpackage.cnb" "docker://${IMAGE}:${{ steps.event.outputs.tag_major }}" - sudo skopeo copy "oci-archive:${GITHUB_WORKSPACE}/buildpackage.cnb" "docker://${IMAGE}:latest" + IMAGE="${GITHUB_REPOSITORY_OWNER/-/}/${GITHUB_REPOSITORY#${GITHUB_REPOSITORY_OWNER}/}" # translates 'paketo-buildpacks/bundle-install' to 'paketobuildpacks/bundle-install' + echo "${DOCKERHUB_PASSWORD}" | sudo skopeo login --username "${DOCKERHUB_USERNAME}" --password-stdin ${DOCKERHUB_REGISTRY} + + ./scripts/publish.sh \ + --buildpack-archive ./buildpack.tgz \ + --image-ref "${DOCKERHUB_REGISTRY}/${IMAGE}:${{ steps.event.outputs.tag_full }}" + + ## Validate that the digest pushed to registry matches with the one mentioned on the readme file + pushed_image_index_digest=$(sudo skopeo inspect "docker://${DOCKERHUB_REGISTRY}/${IMAGE}:${{ steps.event.outputs.tag_full }}" | jq -r .Digest) + + if [ "$(cat ./index-digest.sha256)" != "$pushed_image_index_digest" ]; then + echo "Image index digest pushed to registry does not match with the one mentioned on the readme file" + exit 1; + fi + + sudo skopeo copy "docker://${DOCKERHUB_REGISTRY}/${IMAGE}:${{ steps.event.outputs.tag_full }}" "docker://${DOCKERHUB_REGISTRY}/${IMAGE}:${{ steps.event.outputs.tag_minor }}" --multi-arch all + sudo skopeo copy "docker://${DOCKERHUB_REGISTRY}/${IMAGE}:${{ steps.event.outputs.tag_full }}" "docker://${DOCKERHUB_REGISTRY}/${IMAGE}:${{ steps.event.outputs.tag_major }}" --multi-arch all + sudo skopeo copy "docker://${DOCKERHUB_REGISTRY}/${IMAGE}:${{ steps.event.outputs.tag_full }}" "docker://${DOCKERHUB_REGISTRY}/${IMAGE}:latest" --multi-arch all echo "image=${IMAGE}" >> "$GITHUB_OUTPUT" - echo "digest=$(sudo skopeo inspect "oci-archive:${GITHUB_WORKSPACE}/buildpackage.cnb" | jq -r .Digest)" >> "$GITHUB_OUTPUT" + echo "digest=$pushed_image_index_digest" >> "$GITHUB_OUTPUT" + + - name: Push to GCR + if: ${{ steps.parse_configs.outputs.push_to_gcr == 'true' }} + run: | + echo "${GCR_PASSWORD}" | sudo skopeo login --username "${GCR_USERNAME}" --password-stdin "${GCR_REGISTRY}" + + sudo skopeo copy "docker://${DOCKERHUB_REGISTRY}/${{ steps.push.outputs.image }}" "docker://${GCR_REGISTRY}/${{ github.repository }}:${{ steps.event.outputs.tag_full }}" --multi-arch all + sudo skopeo copy "docker://${DOCKERHUB_REGISTRY}/${{ steps.push.outputs.image }}" "docker://${GCR_REGISTRY}/${{ github.repository }}:${{ steps.event.outputs.tag_minor }}" --multi-arch all + sudo skopeo copy "docker://${DOCKERHUB_REGISTRY}/${{ steps.push.outputs.image }}" "docker://${GCR_REGISTRY}/${{ github.repository }}:${{ steps.event.outputs.tag_major }}" --multi-arch all + sudo skopeo copy "docker://${DOCKERHUB_REGISTRY}/${{ steps.push.outputs.image }}" "docker://${GCR_REGISTRY}/${{ github.repository }}:latest" --multi-arch all - name: Register with CNB Registry uses: docker://ghcr.io/buildpacks/actions/registry/request-add-entry:main with: id: ${{ github.repository }} version: ${{ steps.event.outputs.tag_full }} - address: ${{ steps.push.outputs.image }}@${{ steps.push.outputs.digest }} + address: index.docker.io/${{ steps.push.outputs.image }}@${{ steps.push.outputs.digest }} token: ${{ secrets.PAKETO_BOT_GITHUB_TOKEN }} failure: diff --git a/.gitignore b/.gitignore index cad00482..3dbbf62c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ .DS_Store .idea .bin -/bin /build +/bin +/linux +/darwin +/windows diff --git a/buildpack.toml b/buildpack.toml index 9bf4473a..98d0ed1a 100644 --- a/buildpack.toml +++ b/buildpack.toml @@ -11,10 +11,20 @@ api = "0.7" uri = "https://github.com/paketo-buildpacks/node-engine/blob/main/LICENSE" [metadata] - include-files = ["bin/build", "bin/detect", "bin/run", "bin/optimize-memory", "bin/inspector", "buildpack.toml"] - pre-package = "./scripts/build.sh" - [metadata.default-versions] - node = "20.*.*" + include-files = [ + "buildpack.toml", + "linux/amd64/bin/build", + "linux/amd64/bin/detect", + "linux/amd64/bin/run", + "linux/amd64/bin/setup-symlinks", + "linux/arm64/bin/build", + "linux/arm64/bin/detect", + "linux/arm64/bin/run", + "linux/arm64/bin/setup-symlinks" + ] + + pre-package = "./scripts/build.sh --target linux/amd64 --target linux/arm64" [metadata.default-versions] + node = "20.*.*" [[metadata.dependencies]] checksum = "sha256:abf47264a9a13b2233743ce8a966945388a1a10a56f841310a6d4dd12e18ca9a" @@ -228,3 +238,11 @@ api = "0.7" [[stacks]] id = "*" + +[[targets]] + os = "linux" + arch = "amd64" + +[[targets]] + os = "linux" + arch = "arm64" \ No newline at end of file diff --git a/scripts/build.sh b/scripts/build.sh index c6e1413e..11ab80b4 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -3,10 +3,15 @@ set -eu set -o pipefail +readonly ROOT_DIR="$(cd "$(dirname "${0}")/.." && pwd)" readonly PROGDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" readonly BUILDPACKDIR="$(cd "${PROGDIR}/.." && pwd)" +# shellcheck source=SCRIPTDIR/.util/print.sh +source "${ROOT_DIR}/scripts/.util/print.sh" + function main() { + local targets=() while [[ "${#}" != 0 ]]; do case "${1}" in --help|-h) @@ -15,6 +20,11 @@ function main() { exit 0 ;; + --target) + targets+=("${2}") + shift 2 + ;; + "") # skip if the argument is empty shift 1 @@ -27,8 +37,18 @@ function main() { mkdir -p "${BUILDPACKDIR}/bin" + if [[ ${#targets[@]} -eq 0 ]]; then + targets=("linux/amd64") + util::print::info "Setting default target platform architecture to: linux/amd64" + fi + run::build cmd::build + + ## For backwards compatibility with amd64 wokflows + if [[ ${#targets[@]} -eq 1 && "${targets[0]}" == "linux/amd64" ]]; then + cp -r "${BUILDPACKDIR}/linux/amd64/bin/" "${BUILDPACKDIR}/" + fi } function usage() { @@ -38,39 +58,49 @@ build.sh [OPTIONS] Builds the buildpack executables. OPTIONS - --help -h prints the command usage + --target strings Target platforms to build for. + Targets should be in the format '[os][/arch][/variant]'. + - To specify two different architectures: '--target "linux/amd64" --target "linux/arm64"' + --help -h prints the command usage USAGE } function run::build() { if [[ -f "${BUILDPACKDIR}/run/main.go" ]]; then - pushd "${BUILDPACKDIR}/bin" > /dev/null || return - printf "%s" "Building run... " + pushd "${BUILDPACKDIR}" > /dev/null || return + for target in "${targets[@]}"; do + platform=$(echo "${target}" | cut -d '/' -f1) + arch=$(echo "${target}" | cut -d'/' -f2) - GOOS=linux \ - CGO_ENABLED=0 \ - go build \ - -ldflags="-s -w" \ - -o "run" \ - "${BUILDPACKDIR}/run" + util::print::title "Building run... for platform: ${platform} and arch: ${arch}" - echo "Success!" + GOOS=$platform \ + GOARCH=$arch \ + CGO_ENABLED=0 \ + go build \ + -ldflags="-s -w" \ + -o "${platform}/${arch}/bin/run" \ + "${BUILDPACKDIR}/run" - names=("detect") + echo "Success!" - if [ -f "${BUILDPACKDIR}/extension.toml" ]; then - names+=("generate") - else - names+=("build") - fi + names=("detect") - for name in "${names[@]}"; do - printf "%s" "Linking ${name}... " + if [ -f "${BUILDPACKDIR}/extension.toml" ]; then + names+=("generate") + else + names+=("build") + fi - ln -sf "run" "${name}" + for name in "${names[@]}"; do + printf "%s" "Linking ${name}... " - echo "Success!" + ln -fs "run" "${platform}/${arch}/bin/${name}" + + echo "Success!" + done done + popd > /dev/null || return fi } @@ -80,21 +110,26 @@ function cmd::build() { local name for src in "${BUILDPACKDIR}"/cmd/*; do name="$(basename "${src}")" - - if [[ -f "${src}/main.go" ]]; then - printf "%s" "Building ${name}... " - - GOOS="linux" \ - CGO_ENABLED=0 \ - go build \ - -ldflags="-s -w" \ - -o "${BUILDPACKDIR}/bin/${name}" \ - "${src}/main.go" - - echo "Success!" - else - printf "%s" "Skipping ${name}... " - fi + for target in "${targets[@]}"; do + platform=$(echo "${target}" | cut -d '/' -f1) + arch=$(echo "${target}" | cut -d'/' -f2) + + if [[ -f "${src}/main.go" ]]; then + util::print::title "Building ${name}... for platform: ${platform} and arch: ${arch}" + + GOOS=$platform \ + GOARCH=$arch \ + CGO_ENABLED=0 \ + go build \ + -ldflags="-s -w" \ + -o "${BUILDPACKDIR}/${platform}/${arch}/bin/${name}" \ + "${src}/main.go" + + echo "Success!" + else + printf "%s" "Skipping ${name}... " + fi + done done fi } diff --git a/scripts/package.sh b/scripts/package.sh index 916363eb..cb79bfdd 100755 --- a/scripts/package.sh +++ b/scripts/package.sh @@ -144,26 +144,15 @@ function buildpackage::create() { util::print::title "Packaging ${buildpack_type}... ${output}" - if [ "$buildpack_type" == "extension" ]; then - cwd=$(pwd) - cd ${BUILD_DIR} - mkdir cnbdir - cd cnbdir - cp ../buildpack.tgz . - tar -xvf buildpack.tgz - rm buildpack.tgz - - pack \ - extension package "${output}" \ - --format file - - cd $cwd - else - pack \ - buildpack package "${output}" \ - --path "${BUILD_DIR}/buildpack.tgz" \ - --format file - fi + mkdir ${BUILD_DIR}/cnbdir + tar -xvf ${BUILD_DIR}/buildpack.tgz -C ${BUILD_DIR}/cnbdir + + pack \ + "${buildpack_type}" package "${output}" \ + --path ${BUILD_DIR}/cnbdir \ + --format file + + rm -rf ${BUILD_DIR}/cnbdir } main "${@:-}" \ No newline at end of file diff --git a/scripts/publish.sh b/scripts/publish.sh new file mode 100755 index 00000000..0c65d5fa --- /dev/null +++ b/scripts/publish.sh @@ -0,0 +1,129 @@ +#!/usr/bin/env bash + +set -eu +set -o pipefail + +readonly ROOT_DIR="$(cd "$(dirname "${0}")/.." && pwd)" +readonly BIN_DIR="${ROOT_DIR}/.bin" + +# shellcheck source=SCRIPTDIR/.util/tools.sh +source "${ROOT_DIR}/scripts/.util/tools.sh" + +# shellcheck source=SCRIPTDIR/.util/print.sh +source "${ROOT_DIR}/scripts/.util/print.sh" + +function main { + local buildpack_archive image_ref token + token="" + + while [[ "${#}" != 0 ]]; do + case "${1}" in + --buildpack-archive | -b) + buildpack_archive="${2}" + shift 2 + ;; + + --image-ref | -i) + image_ref+=("${2}") + shift 2 + ;; + + --token | -t) + token="${2}" + shift 2 + ;; + + --help | -h) + shift 1 + usage + exit 0 + ;; + + "") + # skip if the argument is empty + shift 1 + ;; + + *) + util::print::error "unknown argument \"${1}\"" + ;; + esac + done + + if [[ -z "${image_ref:-}" ]]; then + usage + echo + util::print::error "--image-ref is required" + fi + + if [[ -z "${buildpack_archive:-}" ]]; then + util::print::info "Using default buildpack archive path: ${ROOT_DIR}/build/buildpack.tgz" + buildpack_archive="${ROOT_DIR}/build/buildpack.tgz" + fi + + repo::prepare + + tools::install "${token}" + + buildpack_type=buildpack + if [ -f "${ROOT_DIR}/extension.toml" ]; then + buildpack_type=extension + fi + + buildpack::publish "${image_ref}" "${buildpack_type}" +} + +function usage() { + cat <<-USAGE +publish.sh --version [OPTIONS] + +Publishes a buildpack or an extension in to a registry. + +OPTIONS + -h, --help Prints the command usage + -b, --buildpack-archive Path to the buildpack arhive (default: ${ROOT_DIR}/build/buildpack.tgz) (optional) + -i, --image-ref List of image reference to publish to (required) + -t, --token Token used to download assets from GitHub (e.g. jam, pack, etc) (optional) +USAGE +} + +function repo::prepare() { + util::print::title "Preparing repo..." + + mkdir -p "${BIN_DIR}" + + export PATH="${BIN_DIR}:${PATH}" +} + +function tools::install() { + local token + token="${1}" + + util::tools::pack::install \ + --directory "${BIN_DIR}" \ + --token "${token}" +} + +function buildpack::publish() { + + local image_ref buildpack_type + image_ref="${1}" + buildpack_type="${2}" + + util::print::title "Publishing ${buildpack_type}..." + + util::print::info "Extracting archive..." + tmp_dir=$(mktemp -d -p $ROOT_DIR) + tar -xvf $buildpack_archive -C $tmp_dir + + util::print::info "Publishing ${buildpack_type} to ${image_ref}" + pack \ + buildpack package $image_ref \ + --path $tmp_dir \ + --format image \ + --publish + + rm -rf $tmp_dir +} + +main "${@:-}" From 056435498d03ea2d9918bb349e5792239d8b182e Mon Sep 17 00:00:00 2001 From: Ralf Pannemans Date: Fri, 28 Mar 2025 13:13:39 +0100 Subject: [PATCH 3/3] Fix buildpack.toml --- buildpack.toml | 11 ++++++++--- scripts/.syncignore | 3 +++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/buildpack.toml b/buildpack.toml index 98d0ed1a..6c3cb0ba 100644 --- a/buildpack.toml +++ b/buildpack.toml @@ -16,14 +16,19 @@ api = "0.7" "linux/amd64/bin/build", "linux/amd64/bin/detect", "linux/amd64/bin/run", - "linux/amd64/bin/setup-symlinks", + "linux/amd64/bin/optimize-memory, + "linux/amd64/bin/inspector, "linux/arm64/bin/build", "linux/arm64/bin/detect", "linux/arm64/bin/run", - "linux/arm64/bin/setup-symlinks" + "linux/arm64/bin/optimize-memory, + "linux/arm64/bin/inspector, + "buildpack.toml" ] - pre-package = "./scripts/build.sh --target linux/amd64 --target linux/arm64" [metadata.default-versions] + pre-package = "./scripts/build.sh --target linux/amd64 --target linux/arm64" + + [metadata.default-versions] node = "20.*.*" [[metadata.dependencies]] diff --git a/scripts/.syncignore b/scripts/.syncignore index ac5fd814..0fb89bb8 100644 --- a/scripts/.syncignore +++ b/scripts/.syncignore @@ -1 +1,4 @@ options.json +build.sh +package.sh +publish.sh \ No newline at end of file