Skip to content
Merged
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
72 changes: 52 additions & 20 deletions .github/workflows/update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ defaults:
run:
shell: 'bash -Eeuo pipefail -x {0}'

# the job pushes to the default branch and force-pushes a shared branch on the
# official-images fork; never let two runs do that at the same time
concurrency:
group: update-dockerfiles
cancel-in-progress: false

jobs:
update:
name: Update Dockerfiles
Expand All @@ -35,6 +41,11 @@ jobs:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
with:
fetch-depth: 0
# always work from the current tip of the default branch, not from the
# sha the event was created with: a re-run of this workflow reuses the
# original event sha, which would re-apply (and re-push) a commit an
# earlier run already landed
ref: ${{ github.event.repository.default_branch }}
# don't leave the token in .git/config for later steps (e.g. the bashbrew
# checkout and the official-images clone); the push below authenticates explicitly
persist-credentials: false
Expand Down Expand Up @@ -83,26 +94,43 @@ jobs:
# build a message following the existing convention:
# "Update <major> to <version>" for a Ghost bump
# "Update <major> to CLI <version>" for a Ghost-CLI bump
#
# when update.sh produced nothing (e.g. this is a re-run after an earlier
# run already committed), reuse the message/sha of the commit that last
# touched versions.json so the upstream PR still describes the right bump
- name: Compute commit message
id: message
if: steps.changes.outputs.changed == 'true'
env:
CHANGED: ${{ steps.changes.outputs.changed }}
run: |
old="$(git show HEAD:versions.json 2>/dev/null || echo '{}')"
message="$(jq --raw-output --null-input \
--argjson old "$old" \
--argjson new "$(cat versions.json)" '
[ $new | to_entries[] | .key as $k | .value as $v
| ( if ($old[$k].version // null) != $v.version
then "Update \($k) to \($v.version)" else empty end ),
( if (($old[$k].cli.version) // null) != $v.cli.version
then "Update \($k) to CLI \($v.cli.version)" else empty end )
]
| join(", ")
')"
if [ "$CHANGED" = 'true' ]; then
old="$(git show HEAD:versions.json 2>/dev/null || echo '{}')"
message="$(jq --raw-output --null-input \
--argjson old "$old" \
--argjson new "$(cat versions.json)" '
[ $new | to_entries[] | .key as $k | .value as $v
| ( if ($old[$k].version // null) != $v.version
then "Update \($k) to \($v.version)" else empty end ),
( if (($old[$k].cli.version) // null) != $v.cli.version
then "Update \($k) to CLI \($v.cli.version)" else empty end )
]
| join(", ")
')"
sha=''
else
message="$(git log -1 --pretty=%s -- versions.json)"
sha="$(git log -1 --pretty=%H -- versions.json)"
fi
if [ -z "$message" ]; then
message='Update Dockerfiles'
fi
echo "message=$message" >> "$GITHUB_OUTPUT"
if [ -z "$sha" ]; then
sha="$(git rev-parse HEAD)"
fi
{
echo "message=$message"
echo "sha=$sha"
} >> "$GITHUB_OUTPUT"

- name: Print diff (dry run)
if: steps.inputs.outputs.dry_run == 'true'
Expand All @@ -127,18 +155,21 @@ jobs:

# bashbrew is required by generate-stackbrew-library.sh to resolve parent image arches
- name: Install Bashbrew
if: steps.inputs.outputs.dry_run != 'true' && steps.changes.outputs.changed == 'true' && steps.inputs.outputs.make_image_pr == 'true'
if: steps.inputs.outputs.dry_run != 'true' && steps.inputs.outputs.make_image_pr == 'true'
uses: ./.github/actions/bashbrew/

# deliberately not gated on steps.changes: re-running the workflow after a
# failed push/PR here must be able to retry this step on its own, and the
# library/ghost diff below is the real no-op guard
- name: Open official-images PR
if: steps.inputs.outputs.dry_run != 'true' && steps.changes.outputs.changed == 'true' && steps.inputs.outputs.make_image_pr == 'true'
if: steps.inputs.outputs.dry_run != 'true' && steps.inputs.outputs.make_image_pr == 'true'
# avoid -x here so the auth token is not echoed into the logs
shell: 'bash -Eeuo pipefail {0}'
env:
GH_TOKEN: ${{ secrets.OFFICIAL_IMAGES_PR_TOKEN }}
FORK_REPO: ${{ steps.inputs.outputs.official_images_fork_repo }}
COMMIT_MESSAGE: ${{ steps.message.outputs.message }}
HEAD_SHA: ${{ steps.commit.outputs.sha }}
HEAD_SHA: ${{ steps.commit.outputs.sha || steps.message.outputs.sha }}
run: |
# configure git to authenticate via the provided token (no token in URLs/logs)
gh auth setup-git
Expand All @@ -158,14 +189,15 @@ jobs:
git config user.name 'Ghost-Slimer'
git config user.email 'ghost-slimer@users.noreply.github.com'
# always (re)create the update-ghost branch and force-push, overriding any existing one
git checkout -b update-ghost
git checkout -B update-ghost
git add library/ghost
git commit -m "$COMMIT_MESSAGE"
git push --force origin update-ghost

forkOwner="${FORK_REPO%%/*}"
if [ -n "$(gh pr list --repo docker-library/official-images --head "$forkOwner:update-ghost" --json number --jq '.[].number')" ]; then
echo "PR already exists for $forkOwner:update-ghost; force-pushed branch is enough."
existingPr="$(gh pr list --repo docker-library/official-images --head "$forkOwner:update-ghost" --state open --json url --jq '.[].url')"
if [ -n "$existingPr" ]; then
echo "PR already exists for $forkOwner:update-ghost ($existingPr); force-pushed branch is enough."
else
gh pr create \
--repo docker-library/official-images \
Expand Down
Loading