mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-17 08:02:12 -06:00
b376b13fec
* feat(docker): schedule image refreshes * docs(docker): explain weekly image refreshes * test(scripts): gate workflow-step execution on bash 4 mapfile support Stock macOS bash 3.2 lacks mapfile; CI truth is Linux bash 5. * test: cover docker-release suffix threading and sanctioned second caller * test(codex): wire run-attempt-state into the attempt-extra project #123345 added the file without a project owner; the full-suite coverage guard fails for any PR that runs it. * fix(ci): run build-artifacts PR validation on hosted runners ci-build-artifacts-testbox.yml pinned PR runs to blacksmith-16vcpu and ran Testbox lifecycle steps unconditionally, so the prepare-run landing gate starved for every PR during a Blacksmith outage even with OPENCLAW_CI_RUNNER_BACKEND=github. PR events now build on ubuntu-24.04 with dispatch-only Testbox steps, mirroring ci-check-testbox.yml. * test(ci): align build-artifacts dispatch guard
139 lines
4.5 KiB
YAML
139 lines
4.5 KiB
YAML
name: Docker Image Refresh
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
channel:
|
|
description: Release channel to rebuild
|
|
required: false
|
|
default: both
|
|
type: choice
|
|
options:
|
|
- stable
|
|
- extended-stable
|
|
- both
|
|
dry_run:
|
|
description: Resolve and summarize without publishing
|
|
required: false
|
|
default: false
|
|
type: boolean
|
|
schedule:
|
|
- cron: "17 3 * * 1"
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
env:
|
|
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
|
|
|
|
jobs:
|
|
plan:
|
|
runs-on: ubuntu-24.04
|
|
permissions:
|
|
contents: read
|
|
outputs:
|
|
dry_run: ${{ steps.plan.outputs.dry_run }}
|
|
image_tag_suffix: ${{ steps.plan.outputs.image_tag_suffix }}
|
|
matrix: ${{ steps.plan.outputs.matrix }}
|
|
steps:
|
|
- name: Require a main-branch run
|
|
env:
|
|
WORKFLOW_REF: ${{ github.ref }}
|
|
run: |
|
|
set -euo pipefail
|
|
if [[ "${WORKFLOW_REF}" != "refs/heads/main" ]]; then
|
|
echo "::error::Docker image refresh must run from main; got ${WORKFLOW_REF}."
|
|
exit 1
|
|
fi
|
|
|
|
- name: Checkout trusted refresh tooling
|
|
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
with:
|
|
ref: ${{ github.sha }}
|
|
fetch-depth: 0
|
|
persist-credentials: false
|
|
|
|
- name: Resolve refresh plan
|
|
id: plan
|
|
shell: bash
|
|
env:
|
|
CHANNEL: ${{ github.event_name == 'schedule' && 'both' || inputs.channel }}
|
|
DRY_RUN: ${{ github.event_name == 'schedule' && 'false' || inputs.dry_run }}
|
|
run: |
|
|
set -euo pipefail
|
|
current="$(git tag --list 'v*' | node scripts/lib/docker-release-policy.mjs --current)"
|
|
stable_tag="$(jq -er '.stable.tag' <<< "${current}")"
|
|
extended_stable_tag="$(jq -er '.extendedStable.tag' <<< "${current}")"
|
|
stable_sha="$(git rev-parse "refs/tags/${stable_tag}^{commit}")"
|
|
extended_stable_sha="$(git rev-parse "refs/tags/${extended_stable_tag}^{commit}")"
|
|
suffix="-r$(date -u +%Y%m%d)"
|
|
|
|
stable_entry="$(
|
|
jq -cn \
|
|
--arg channel stable \
|
|
--arg tag "${stable_tag}" \
|
|
--arg release_sha "${stable_sha}" \
|
|
'{channel: $channel, tag: $tag, release_sha: $release_sha}'
|
|
)"
|
|
extended_stable_entry="$(
|
|
jq -cn \
|
|
--arg channel extended-stable \
|
|
--arg tag "${extended_stable_tag}" \
|
|
--arg release_sha "${extended_stable_sha}" \
|
|
'{channel: $channel, tag: $tag, release_sha: $release_sha}'
|
|
)"
|
|
case "${CHANNEL}" in
|
|
stable)
|
|
matrix="$(jq -cn --argjson stable "${stable_entry}" '[$stable]')"
|
|
;;
|
|
extended-stable)
|
|
matrix="$(jq -cn --argjson extended "${extended_stable_entry}" '[$extended]')"
|
|
;;
|
|
both)
|
|
matrix="$(
|
|
jq -cn \
|
|
--argjson stable "${stable_entry}" \
|
|
--argjson extended "${extended_stable_entry}" \
|
|
'[$stable, $extended]'
|
|
)"
|
|
;;
|
|
*)
|
|
echo "::error::Unsupported Docker refresh channel: ${CHANNEL}"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
{
|
|
echo "dry_run=${DRY_RUN}"
|
|
echo "image_tag_suffix=${suffix}"
|
|
echo "matrix=${matrix}"
|
|
} >> "${GITHUB_OUTPUT}"
|
|
{
|
|
echo "## Docker image refresh plan"
|
|
echo "- Stable: ${stable_tag} (${stable_sha})"
|
|
echo "- Extended stable: ${extended_stable_tag} (${extended_stable_sha})"
|
|
echo "- Image tag suffix: ${suffix}"
|
|
echo "- Selected channel: ${CHANNEL}"
|
|
echo "- Dry run: ${DRY_RUN}"
|
|
} >> "${GITHUB_STEP_SUMMARY}"
|
|
|
|
publish:
|
|
name: Refresh ${{ matrix.channel }} Docker images
|
|
needs: plan
|
|
if: needs.plan.outputs.dry_run != 'true'
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include: ${{ fromJSON(needs.plan.outputs.matrix) }}
|
|
uses: ./.github/workflows/docker-release.yml
|
|
with:
|
|
tag: ${{ matrix.tag }}
|
|
release_sha: ${{ matrix.release_sha }}
|
|
image_tag_suffix: ${{ needs.plan.outputs.image_tag_suffix }}
|
|
secrets:
|
|
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
permissions:
|
|
contents: read
|
|
packages: write
|