Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/.patch_files
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ README.md
go.mod
go.sum
scripts/.util/builders.sh
scripts/.util/implementation.sh
scripts/.util/print.sh
scripts/.util/tools.json
scripts/.util/tools.sh
Expand Down
297 changes: 293 additions & 4 deletions .github/workflows/create-draft-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ jobs:
runs-on: ubuntu-24.04
outputs:
builders: ${{ steps.builders.outputs.builders }}
integration: ${{ steps.config.outputs.integration }}
multi: ${{ steps.config.outputs.multi }}
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand All @@ -36,6 +38,12 @@ jobs:
go-version-file: go.mod
- name: Run Unit Tests
run: ./scripts/unit.sh
- name: Read Implementation Config
id: config
run: |
source "${GITHUB_WORKSPACE}/scripts/.util/implementation.sh"
echo "integration=$(util::implementation::integration "${GITHUB_WORKSPACE}")" >> "$GITHUB_OUTPUT"
echo "multi=$(util::implementation::is_multi "${GITHUB_WORKSPACE}")" >> "$GITHUB_OUTPUT"
- name: Get builders from integration.json
id: builders
run: |
Expand All @@ -48,6 +56,7 @@ jobs:
name: Integration Tests
runs-on: ubuntu-24.04
needs: unit
if: ${{ needs.unit.outputs.integration == 'true' }}
permissions:
contents: read
packages: read # pull builder images for integration tests
Expand Down Expand Up @@ -89,15 +98,17 @@ jobs:
TMPDIR: "${{ runner.temp }}"
GIT_TOKEN: ${{ github.token }}

# Standard implementation: one buildpack, packaged with jam/pack.
release:
name: Release
runs-on: ubuntu-24.04
needs: integration
needs: [unit, integration]
if: ${{ needs.unit.outputs.multi != 'true' }}
permissions:
contents: write # create and update the draft release
services:
registry:
image: registry:3@sha256:ddf754342cfc8acc51a56d5d0ab6af06826461864460636d8bd5c546dab2a7b8
image: registry:3@sha256:82f6ff4a7f982960c8aa51617fea3aabc485df6e55cce80d22deb1de36f1bc3c
ports:
- 5000:5000

Expand Down Expand Up @@ -257,11 +268,289 @@ jobs:
draft: true
assets: ${{ steps.create_release_assets.outputs.release_assets }}

# Multi-implementation: a combined buildpack plus one per component.
release-prep:
name: Release Prep (multi)
runs-on: ubuntu-24.04
needs: [unit, integration]
if: ${{ always() && needs.unit.outputs.multi == 'true' && needs.unit.result == 'success' && (needs.integration.result == 'success' || needs.integration.result == 'skipped') }}
permissions:
contents: write # reset the draft release
outputs:
tag: ${{ steps.tag.outputs.tag }}
buildpack_type: ${{ steps.get_buildpack_type.outputs.buildpack_type }}
buildpacks: ${{ steps.config.outputs.buildpacks }}
combined: ${{ steps.config.outputs.combined }}
components: ${{ steps.config.outputs.components }}
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
fetch-tags: true

- name: Setup Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod

- name: Read Implementation Config
id: config
run: |
source "${GITHUB_WORKSPACE}/scripts/.util/implementation.sh"
echo "buildpacks=$(util::implementation::buildpacks "${GITHUB_WORKSPACE}")" >> "$GITHUB_OUTPUT"
echo "combined=$(util::implementation::combined "${GITHUB_WORKSPACE}")" >> "$GITHUB_OUTPUT"
echo "components=$(util::implementation::components "${GITHUB_WORKSPACE}")" >> "$GITHUB_OUTPUT"

- name: Reset Draft Release
id: reset
uses: paketo-buildpacks/github-config/actions/release/reset-draft@main
with:
repo: ${{ github.repository }}
token: ${{ github.token }}

- name: Calculate Semver Tag
if: github.event.inputs.version == ''
id: semver
uses: paketo-buildpacks/github-config/actions/tag/calculate-semver@main
with:
repo: ${{ github.repository }}
token: ${{ github.token }}
ref-name: ${{ github.ref_name }}

- name: Set Release Tag
id: tag
env:
INPUT_VERSION: ${{ github.event.inputs.version }}
SEMVER_TAG: ${{ steps.semver.outputs.tag }}
run: |
tag="${INPUT_VERSION}"
if [ -z "${tag}" ]; then
tag="${SEMVER_TAG}"
fi
echo "tag=${tag}" >> "$GITHUB_OUTPUT"

- name: Get buildpack type
id: get_buildpack_type
run: |
if [ -f "extension.toml" ]; then
echo "buildpack_type=extension" >> "$GITHUB_OUTPUT"
else
echo "buildpack_type=buildpack" >> "$GITHUB_OUTPUT"
fi

- name: Package
env:
TAG: ${{ steps.tag.outputs.tag }}
run: ./scripts/package.sh --version "${TAG}"

- name: Upload build artifacts
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: build-artifacts
path: build/
retention-days: 1

generate-notes:
name: Generate Release Notes (${{ matrix.buildpack }})
runs-on: ubuntu-24.04
needs: [unit, release-prep]
if: ${{ needs.unit.outputs.multi == 'true' }}
services:
registry:
image: registry:3@sha256:82f6ff4a7f982960c8aa51617fea3aabc485df6e55cce80d22deb1de36f1bc3c
ports:
- 5000:5000
strategy:
matrix:
buildpack: ${{ fromJSON(needs.release-prep.outputs.buildpacks) }}
fail-fast: false
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Download build artifacts
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: build-artifacts
path: build/

# Use the full action for the combined buildpack so the release notes include
# the Changes section (PR list since the last release).
- name: Create Release Notes
id: create-release-notes
if: matrix.buildpack == needs.release-prep.outputs.combined
uses: paketo-buildpacks/github-config/actions/release/notes@main
with:
repo: ${{ github.repository }}
token: ${{ secrets.PAKETO_BOT_GITHUB_TOKEN }}
buildpack_type: ${{ needs.release-prep.outputs.buildpack_type }}
buildpackage_path: build/${{ matrix.buildpack }}.cnb

- name: Write Release Notes to file
if: matrix.buildpack == needs.release-prep.outputs.combined
env:
RELEASE_BODY: ${{ steps.create-release-notes.outputs.release_body }}
run: |
printf '%s' "${RELEASE_BODY}" > ./release_notes_raw

# For the component buildpacks, run jam summarize directly. The Changes
# section would be identical for every component and would otherwise be
# duplicated in the final release notes.
- name: Summarize Component Release Notes
if: matrix.buildpack != needs.release-prep.outputs.combined
env:
BUILDPACK_TYPE: ${{ needs.release-prep.outputs.buildpack_type }}
BUILDPACK: ${{ matrix.buildpack }}
run: |
jam_version="$(curl "https://api.github.com/repos/paketo-buildpacks/jam/releases/latest" \
--fail-with-body --show-error \
--header "Authorization: token ${{ secrets.PAKETO_BOT_GITHUB_TOKEN }}" \
--location --silent \
| jq -r -S .tag_name)"

mkdir -p "${HOME}/bin"
export PATH="${HOME}/bin:${PATH}"
curl "https://github.com/paketo-buildpacks/jam/releases/download/${jam_version}/jam-linux" \
--fail-with-body --show-error --silent --location \
--output "${HOME}/bin/jam"
chmod +x "${HOME}/bin/jam"

jam summarize \
--"${BUILDPACK_TYPE}" "build/${BUILDPACK}.cnb" \
--format markdown > ./release_notes_raw

- name: Get Image Digest
id: image_digest
env:
BUILDPACK_TYPE: ${{ needs.release-prep.outputs.buildpack_type }}
BUILDPACK: ${{ matrix.buildpack }}
run: |
image_name="localhost:5000/${BUILDPACK}:latest"

./scripts/publish.sh \
--buildpack-type "${BUILDPACK_TYPE}" \
--archive-path "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 Release Notes
env:
BUILDPACK: ${{ matrix.buildpack }}
IMAGE_DIGEST: ${{ steps.image_digest.outputs.digest }}
run: |
sed -E \
"s/\*\*Digest:\*\* \`sha256:[a-f0-9]{64}\`/\*\*Digest:\*\* \`${IMAGE_DIGEST}\`/" \
./release_notes_raw > "./release_notes_${BUILDPACK}"

printf '%s' "${IMAGE_DIGEST}" > "./${BUILDPACK}-index-digest.sha256"

- name: Upload release notes artifact
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: release-notes-${{ matrix.buildpack }}
path: |
./release_notes_${{ matrix.buildpack }}
./${{ matrix.buildpack }}-index-digest.sha256
retention-days: 1

release-multi:
name: Release (multi)
runs-on: ubuntu-24.04
needs: [unit, release-prep, generate-notes]
if: ${{ needs.unit.outputs.multi == 'true' }}
permissions:
contents: write # create and update the draft release
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Download build artifacts
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: build-artifacts
path: build/

- name: Download all release notes artifacts
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
pattern: release-notes-*
merge-multiple: true
path: ./release-notes/

- name: Assemble Release Notes
env:
COMBINED: ${{ needs.release-prep.outputs.combined }}
COMPONENTS: ${{ needs.release-prep.outputs.components }}
run: |
cat "./release-notes/release_notes_${COMBINED}" > ./release_notes
for buildpack in $(jq -r '.[]' <<< "${COMPONENTS}"); do
printf "\n\n---\n\n" >> ./release_notes
cat "./release-notes/release_notes_${buildpack}" >> ./release_notes
done

- name: Create release assets
id: create_release_assets
env:
REPO_NAME: ${{ github.event.repository.name }}
TAG: ${{ needs.release-prep.outputs.tag }}
run: |
source "${GITHUB_WORKSPACE}/scripts/.util/implementation.sh"

release_assets='[]'

for filepath in build/*.cnb; do
filename=$(basename "$filepath")
name="${filename%.cnb}"
suffix="$(util::implementation::asset-suffix "${GITHUB_WORKSPACE}" "${name}")"
asset_name="${REPO_NAME}-${TAG}${suffix}.cnb"
release_assets=$(echo "$release_assets" | jq --arg name "${asset_name}" --arg path "$filepath" \
'. + [{"path": $path, "name": $name, "content_type": "application/gzip"}]')
done

for filepath in build/*.tgz; do
filename=$(basename "$filepath")
name="${filename%.tgz}"
suffix="$(util::implementation::asset-suffix "${GITHUB_WORKSPACE}" "${name}")"
asset_name="${REPO_NAME}-${TAG}${suffix}.tgz"
release_assets=$(echo "$release_assets" | jq --arg name "${asset_name}" --arg path "$filepath" \
'. + [{"path": $path, "name": $name, "content_type": "application/gzip"}]')
done

for filepath in ./release-notes/*-index-digest.sha256; do
filename=$(basename "$filepath")
name="${filename%-index-digest.sha256}"
suffix="$(util::implementation::asset-suffix "${GITHUB_WORKSPACE}" "${name}")"
asset_name="${REPO_NAME}-${TAG}${suffix}-index-digest.sha256"
release_assets=$(echo "$release_assets" | jq --arg name "${asset_name}" --arg path "$filepath" \
'. + [{"path": $path, "name": $name, "content_type": "text/plain"}]')
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
with:
repo: ${{ github.repository }}
token: ${{ secrets.PAKETO_BOT_GITHUB_TOKEN }}
tag_name: v${{ needs.release-prep.outputs.tag }}
target_commitish: ${{ github.sha }}
name: v${{ needs.release-prep.outputs.tag }}
body_filepath: "./release_notes"
draft: true
assets: ${{ steps.create_release_assets.outputs.release_assets }}

failure:
name: Alert on Failure
runs-on: ubuntu-24.04
needs: [ unit, integration, release ]
if: ${{ always() && needs.unit.result == 'failure' || needs.integration.result == 'failure' || needs.release.result == 'failure' }}
needs: [unit, integration, release, release-prep, generate-notes, release-multi]
if: ${{ always() && (needs.unit.result == 'failure' || needs.integration.result == 'failure' || needs.release.result == 'failure' || needs.release-prep.result == 'failure' || needs.generate-notes.result == 'failure' || needs.release-multi.result == 'failure') }}
permissions:
contents: read
issues: write
Expand Down
26 changes: 17 additions & 9 deletions .github/workflows/label-pr.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Set / Validate PR Labels
on:
pull_request_target:
pull_request:
branches:
- main
types:
Expand All @@ -22,9 +22,23 @@ jobs:
name: Ensure Minimal Semver Labels
runs-on: ubuntu-24.04
permissions:
issues: read # read the issue's current labels
pull-requests: read # read the pull request's metadata
contents: read # check out the repository to determine which files changed
issues: write # add the semver label
pull-requests: write # update the pull request's labels
steps:
- name: Detect existing label
id: detect_label
run: |
set -euo pipefail
label_exists=$(jq -r '.pull_request.labels // [] | map(.name) | length > 0' "${GITHUB_EVENT_PATH}")
echo "label_exists=${label_exists}" >> "${GITHUB_OUTPUT}"

- name: Auto-label Semver
if: ${{ github.event.pull_request.head.repo.full_name == github.repository && steps.detect_label.outputs.label_exists != 'true' }}
uses: paketo-buildpacks/github-config/actions/pull-request/auto-semver-label@main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Check Minimal Semver Labels
uses: mheap/github-action-required-labels@23e10fde7e062233401931a0eece796cd9bf3177 # v5.6.0
with:
Expand All @@ -33,9 +47,3 @@ jobs:
mode: exactly
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Auto-label Semver
if: ${{ failure() }}
uses: paketo-buildpacks/github-config/actions/pull-request/auto-semver-label@main
env:
GITHUB_TOKEN: ${{ secrets.PAKETO_BOT_GITHUB_TOKEN }}
Loading
Loading