mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-13 06:06:38 +00:00
ci: add pull_request_target image build/mirror workflow flow
This commit is contained in:
16 files changed
+384
-60
No files matched your search
@@ -7,13 +7,28 @@ on:
|
||||
description: "Space-separated distro list"
|
||||
required: true
|
||||
type: string
|
||||
checkout_ref:
|
||||
description: "Optional git ref to checkout before build (default: event ref)"
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
image_tag:
|
||||
description: "Optional image tag override (default: ci-${github.sha})"
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
concurrency_channel:
|
||||
description: "Optional channel to separate concurrency groups between callers"
|
||||
required: false
|
||||
type: string
|
||||
default: "default"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
concurrency:
|
||||
group: infinito-build-${{ github.ref }}
|
||||
group: infinito-build-${{ github.repository }}-${{ inputs.concurrency_channel }}-${{ inputs.checkout_ref || github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
@@ -22,7 +37,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.out.outputs.matrix }}
|
||||
image_tag: ci-${{ github.sha }}
|
||||
image_tag: ${{ steps.out.outputs.image_tag }}
|
||||
steps:
|
||||
- name: Install jq
|
||||
run: |
|
||||
@@ -36,8 +51,14 @@ jobs:
|
||||
set -euo pipefail
|
||||
distros="${{ inputs.distros }}"
|
||||
json="$(printf '%s' "$distros" | jq -Rc 'split(" ") | map(select(length>0))')"
|
||||
image_tag="${{ inputs.image_tag }}"
|
||||
if [ -z "${image_tag}" ]; then
|
||||
image_tag="ci-${GITHUB_SHA}"
|
||||
fi
|
||||
echo "matrix=${json}" >> "$GITHUB_OUTPUT"
|
||||
echo "image_tag=${image_tag}" >> "$GITHUB_OUTPUT"
|
||||
echo "Using matrix: ${json}"
|
||||
echo "Using image tag: ${image_tag}"
|
||||
|
||||
build:
|
||||
name: 🏗️ Build image (${{ matrix.distro }})
|
||||
@@ -50,8 +71,19 @@ jobs:
|
||||
distro: ${{ fromJson(needs.prepare.outputs.matrix) }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
- name: Checkout trusted workflow repo (helpers)
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.sha }}
|
||||
persist-credentials: false
|
||||
|
||||
- name: Checkout source to build
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
repository: ${{ github.repository }}
|
||||
ref: ${{ inputs.checkout_ref || github.ref }}
|
||||
path: _src
|
||||
persist-credentials: false
|
||||
|
||||
- name: Disk pressure (start)
|
||||
shell: bash
|
||||
@@ -96,39 +128,24 @@ jobs:
|
||||
run: echo "owner=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Build & push (retry 7x, 20s)
|
||||
if: ${{ !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
env:
|
||||
BUILD_CONTEXT_DIR: _src
|
||||
MATRIX_DISTRO: ${{ matrix.distro }}
|
||||
IMAGE_TAG: ${{ needs.prepare.outputs.image_tag }}
|
||||
USE_NIX_TOKEN: ${{ !(github.event_name == 'pull_request_target' && github.event.pull_request.head.repo.full_name != github.repository) }}
|
||||
NIX_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
MAX_ATTEMPTS: "7"
|
||||
RETRY_DELAY_SECONDS: "20"
|
||||
run: ./scripts/ci/build_and_push_ci_image.sh
|
||||
|
||||
max_attempts=7
|
||||
retry_delay_seconds=20
|
||||
attempt=1
|
||||
|
||||
while true; do
|
||||
echo "=== Build & push attempt ${attempt}/${max_attempts} ==="
|
||||
|
||||
if docker buildx build \
|
||||
--file ./Dockerfile \
|
||||
--push \
|
||||
--tag "ghcr.io/${{ steps.lower_owner.outputs.owner }}/infinito-${{ matrix.distro }}:${{ needs.prepare.outputs.image_tag }}" \
|
||||
--build-arg "PKGMGR_IMAGE=ghcr.io/kevinveenbirkenbach/pkgmgr-${{ matrix.distro }}:stable" \
|
||||
--build-arg "NIX_CONFIG=access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}" \
|
||||
--cache-from "type=gha,scope=infinito-${{ matrix.distro }}" \
|
||||
--cache-to "type=gha,mode=max,scope=infinito-${{ matrix.distro }}" \
|
||||
.; then
|
||||
echo "Build & push succeeded on attempt ${attempt}/${max_attempts}."
|
||||
break
|
||||
fi
|
||||
|
||||
if [ "${attempt}" -ge "${max_attempts}" ]; then
|
||||
echo "Build & push failed after ${max_attempts} attempts."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Attempt ${attempt} failed. Retrying in ${retry_delay_seconds}s..."
|
||||
sleep "${retry_delay_seconds}"
|
||||
attempt=$((attempt + 1))
|
||||
done
|
||||
- name: Wait for prebuilt image (fork PR)
|
||||
if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository }}
|
||||
env:
|
||||
MATRIX_DISTRO: ${{ matrix.distro }}
|
||||
IMAGE_TAG: ${{ needs.prepare.outputs.image_tag }}
|
||||
run: ./scripts/ci/wait_prebuilt_ci_image.sh
|
||||
|
||||
- name: Disk pressure (post-build)
|
||||
if: always()
|
||||
|
||||
@@ -48,6 +48,7 @@ jobs:
|
||||
uses: ./.github/workflows/build-ci-images.yml
|
||||
with:
|
||||
distros: "arch debian ubuntu fedora centos"
|
||||
concurrency_channel: ci-orchestrator-build-consumer
|
||||
|
||||
# Code Testing
|
||||
test-code-integration:
|
||||
@@ -85,6 +86,8 @@ jobs:
|
||||
# Sync Missing Images
|
||||
images-mirror-missing:
|
||||
uses: ./.github/workflows/images-mirror-missing.yml
|
||||
with:
|
||||
concurrency_channel: ci-orchestrator-mirror-consumer
|
||||
secrets: inherit
|
||||
|
||||
# Deploy tests
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
name: CI (On Pull-Request Target / Build CI Images For Forks)
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
- ready_for_review
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
prepare-fork-merge-ref:
|
||||
if: ${{ github.event.pull_request.head.repo.full_name != github.repository }}
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
checkout_ref: ${{ steps.out.outputs.checkout_ref }}
|
||||
image_tag: ${{ steps.out.outputs.image_tag }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Resolve merge ref and image tag
|
||||
id: out
|
||||
env:
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
PR_MERGE_SHA: ${{ github.event.pull_request.merge_commit_sha || '' }}
|
||||
run: ./scripts/ci/resolve_pr_merge_ref.sh
|
||||
|
||||
build-ci-images-fork:
|
||||
if: ${{ github.event.pull_request.head.repo.full_name != github.repository }}
|
||||
needs: prepare-fork-merge-ref
|
||||
uses: ./.github/workflows/build-ci-images.yml
|
||||
with:
|
||||
distros: "arch debian ubuntu fedora centos"
|
||||
checkout_ref: ${{ needs.prepare-fork-merge-ref.outputs.checkout_ref }}
|
||||
image_tag: ${{ needs.prepare-fork-merge-ref.outputs.image_tag }}
|
||||
concurrency_channel: pr-target-build-producer
|
||||
secrets: inherit
|
||||
@@ -0,0 +1,43 @@
|
||||
name: CI (On Pull-Request Target / Mirror Fork Images)
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
- ready_for_review
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
prepare-fork-merge-ref:
|
||||
if: ${{ github.event.pull_request.head.repo.full_name != github.repository }}
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
checkout_ref: ${{ steps.out.outputs.checkout_ref }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Resolve merge ref
|
||||
id: out
|
||||
env:
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
PR_MERGE_SHA: ${{ github.event.pull_request.merge_commit_sha || '' }}
|
||||
run: ./scripts/ci/resolve_pr_merge_ref.sh
|
||||
|
||||
images-mirror-missing-fork:
|
||||
if: ${{ github.event.pull_request.head.repo.full_name != github.repository }}
|
||||
needs: prepare-fork-merge-ref
|
||||
uses: ./.github/workflows/images-mirror-missing.yml
|
||||
with:
|
||||
repo_root: _pr_source
|
||||
source_repository: ${{ github.repository }}
|
||||
source_ref: ${{ needs.prepare-fork-merge-ref.outputs.checkout_ref }}
|
||||
source_path: _pr_source
|
||||
concurrency_channel: pr-target-mirror-producer
|
||||
concurrency_key: pr-${{ github.event.pull_request.number }}
|
||||
secrets: inherit
|
||||
@@ -7,7 +7,6 @@ concurrency:
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
- "feature/**"
|
||||
- "hotfix/**"
|
||||
@@ -76,7 +75,7 @@ jobs:
|
||||
distros: ${{ needs.pick-distro.outputs.distros }}
|
||||
secrets: inherit
|
||||
|
||||
# Guard job: only allow version releases if the tag commit is contained in origin/master
|
||||
# Guard job: only allow version releases if the tag commit is contained in origin/main
|
||||
release-guard:
|
||||
name: "🛡️ Guard release"
|
||||
if: github.event.created == false && needs.pick-distro.outputs.is_version == 'true'
|
||||
@@ -93,13 +92,13 @@ jobs:
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
- name: Fetch master
|
||||
- name: Fetch main
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
git fetch origin master:refs/remotes/origin/master --force
|
||||
git fetch origin main:refs/remotes/origin/main --force
|
||||
|
||||
- name: "Guard: tag commit must be contained in origin/master"
|
||||
- name: "Guard: tag commit must be contained in origin/main"
|
||||
id: guard
|
||||
shell: bash
|
||||
env:
|
||||
@@ -117,12 +116,12 @@ jobs:
|
||||
tag_sha="$(git rev-list -n 1 "${tag}")"
|
||||
echo "Tag: ${tag} -> ${tag_sha}"
|
||||
|
||||
if git merge-base --is-ancestor "${tag_sha}" "origin/master"; then
|
||||
if git merge-base --is-ancestor "${tag_sha}" "origin/main"; then
|
||||
echo "allowed=true" >> "$GITHUB_OUTPUT"
|
||||
echo "✅ Tag commit is on origin/master"
|
||||
echo "✅ Tag commit is on origin/main"
|
||||
else
|
||||
echo "allowed=false" >> "$GITHUB_OUTPUT"
|
||||
echo "⛔ Tag commit is NOT on origin/master"
|
||||
echo "⛔ Tag commit is NOT on origin/main"
|
||||
fi
|
||||
|
||||
release-version:
|
||||
|
||||
@@ -17,11 +17,36 @@ on:
|
||||
required: false
|
||||
type: string
|
||||
default: "."
|
||||
source_repository:
|
||||
description: "Optional source repository for image config scan (e.g. fork owner/repo)"
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
source_ref:
|
||||
description: "Optional source ref/SHA for image config scan"
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
source_path:
|
||||
description: "Optional checkout path for source_repository/source_ref"
|
||||
required: false
|
||||
type: string
|
||||
default: "_pr_source"
|
||||
images_per_hour:
|
||||
description: "Optional throttle: max images mirrored per hour"
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
concurrency_channel:
|
||||
description: "Optional channel to separate concurrency groups between callers"
|
||||
required: false
|
||||
type: string
|
||||
default: "default"
|
||||
concurrency_key:
|
||||
description: "Optional key (e.g. pr-123) to scope concurrency within a channel"
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
secrets:
|
||||
DOCKERHUB_USERNAME:
|
||||
required: false
|
||||
@@ -33,7 +58,7 @@ permissions:
|
||||
packages: write
|
||||
|
||||
concurrency:
|
||||
group: mirror-images-${{ github.repository }}-${{ github.ref_name }}
|
||||
group: mirror-images-${{ github.repository }}-${{ inputs.concurrency_channel }}-${{ inputs.concurrency_key || github.ref_name }}
|
||||
# Cancel scheduled Mirror sync, because may it works with outdatet mirror lists
|
||||
cancel-in-progress: true
|
||||
|
||||
@@ -52,6 +77,16 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Checkout source repo for scan (optional)
|
||||
if: ${{ inputs.source_repository != '' && inputs.source_ref != '' }}
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
repository: ${{ inputs.source_repository }}
|
||||
ref: ${{ inputs.source_ref }}
|
||||
path: ${{ inputs.source_path }}
|
||||
fetch-depth: 1
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
@@ -69,7 +104,7 @@ jobs:
|
||||
|
||||
# Optional: Docker Hub login to avoid rate limits while mirroring
|
||||
- name: Login to Docker Hub (optional)
|
||||
if: ${{ env.DOCKERHUB_USERNAME != '' && env.DOCKERHUB_TOKEN != '' }}
|
||||
if: ${{ env.DOCKERHUB_USERNAME != '' && env.DOCKERHUB_TOKEN != '' && !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) }}
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
username: ${{ env.DOCKERHUB_USERNAME }}
|
||||
@@ -82,7 +117,16 @@ jobs:
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Wait for mirrored images (fork PR)
|
||||
if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository }}
|
||||
env:
|
||||
GHCR_NAMESPACE: ${{ inputs.ghcr_namespace || github.repository_owner }}
|
||||
GHCR_PREFIX: ${{ inputs.ghcr_prefix || 'mirror' }}
|
||||
REPO_ROOT: ${{ inputs.repo_root || '.' }}
|
||||
run: ./scripts/ci/wait_mirrored_images.sh
|
||||
|
||||
- name: Mirror images to GHCR (only missing, best-effort)
|
||||
if: ${{ !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
git@github.com:infinito-nexus/core.git
|
||||
ssh://git@code.infinito.nexus:2201/infinito/nexus.git
|
||||
ssh://git@git.veen.world:2201/kevinveenbirkenbach/infinito-nexus
|
||||
git@github.com:kevinveenbirkenbach/infinito-nexus.git
|
||||
@@ -146,7 +146,7 @@ def build_single_graph(
|
||||
"id": role,
|
||||
**galaxy_info,
|
||||
"doc_url": f"https://docs.infinito.nexus/roles/{role}/README.html",
|
||||
"source_url": f"https://github.com/kevinveenbirkenbach/infinito-nexus/tree/master/roles/{role}",
|
||||
"source_url": f"https://github.com/infinito-nexus/core/tree/main/roles/{role}",
|
||||
}
|
||||
nodes[role] = node
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ Contributing to Infinito.Nexus
|
||||
|
||||
Want to contribute to the project or explore the source code? Check out our **GitHub repository**:
|
||||
|
||||
- `Infinito.Nexus GitHub Repository <https://s.infinito.nexus/code/tree/master/roles>`_
|
||||
- `Infinito.Nexus GitHub Repository <https://github.com/infinito-nexus/core/tree/main/roles>`_
|
||||
|
||||
Contribution Guidelines
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
vars:
|
||||
docker_git_repository_address: "https://github.com/akaunting/docker.git"
|
||||
docker_git_repository_pull: true
|
||||
docker_git_repository_version: "master"
|
||||
docker_git_repository_version: "master"
|
||||
docker_compose_flush_handlers: true
|
||||
|
||||
- name: "Akaunting | Create first-run marker to disable future setup"
|
||||
|
||||
@@ -15,7 +15,7 @@ For further details on installation, configuration, and upgrades, please refer t
|
||||
- [User_Administration.md](./User_Administration.md)
|
||||
|
||||
For more information about this role, visit the GitHub repositories:
|
||||
- [Mailu](https://s.infinito.nexus/code/tree/master/roles/web-app-mailu)
|
||||
- [Mailu](https://github.com/infinito-nexus/core/tree/main/roles/web-app-mailu)
|
||||
- [Mailu-OIDC](https://github.com/heviat/Mailu-OIDC)
|
||||
|
||||
## Features
|
||||
|
||||
@@ -108,9 +108,9 @@ compose:
|
||||
onboard_enabled: true
|
||||
standalone_enabled: false
|
||||
network_mode: bridge
|
||||
cpus: "1.0"
|
||||
mem_reservation: "256m"
|
||||
mem_limit: "1g"
|
||||
cpus: "2.0"
|
||||
mem_reservation: "1g"
|
||||
mem_limit: "2g"
|
||||
pids_limit: 1024
|
||||
whiteboard:
|
||||
name: "nextcloud-whiteboard"
|
||||
@@ -126,15 +126,15 @@ compose:
|
||||
enabled: true
|
||||
shared: true
|
||||
talk_recording:
|
||||
name: "nextcloud-talk-recording"
|
||||
image: "nextcloud/aio-talk-recording"
|
||||
version: "latest"
|
||||
name: "nextcloud-talk-recording"
|
||||
image: "nextcloud/aio-talk-recording"
|
||||
version: "latest"
|
||||
backup:
|
||||
no_stop_required: true
|
||||
cpus: "2.0"
|
||||
mem_reservation: "2g"
|
||||
mem_limit: "4g"
|
||||
pids_limit: 1024
|
||||
no_stop_required: true
|
||||
cpus: "2.0"
|
||||
mem_reservation: "2g"
|
||||
mem_limit: "6g"
|
||||
pids_limit: 1024
|
||||
css:
|
||||
enabled: false
|
||||
hcaptcha:
|
||||
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
: "${BUILD_CONTEXT_DIR:?Missing BUILD_CONTEXT_DIR}"
|
||||
: "${MATRIX_DISTRO:?Missing MATRIX_DISTRO}"
|
||||
: "${IMAGE_TAG:?Missing IMAGE_TAG}"
|
||||
: "${GITHUB_REPOSITORY_OWNER:?Missing GITHUB_REPOSITORY_OWNER}"
|
||||
: "${USE_NIX_TOKEN:?Missing USE_NIX_TOKEN}"
|
||||
|
||||
max_attempts="${MAX_ATTEMPTS:-7}"
|
||||
retry_delay_seconds="${RETRY_DELAY_SECONDS:-20}"
|
||||
attempt=1
|
||||
|
||||
nix_arg=()
|
||||
if [[ "${USE_NIX_TOKEN}" == "true" ]]; then
|
||||
: "${NIX_GITHUB_TOKEN:?Missing NIX_GITHUB_TOKEN}"
|
||||
nix_arg=( --build-arg "NIX_CONFIG=access-tokens = github.com=${NIX_GITHUB_TOKEN}" )
|
||||
else
|
||||
echo "pull_request_target on fork detected: skipping NIX_CONFIG token build-arg."
|
||||
fi
|
||||
|
||||
while true; do
|
||||
echo "=== Build & push attempt ${attempt}/${max_attempts} ==="
|
||||
|
||||
if docker buildx build \
|
||||
--file "${BUILD_CONTEXT_DIR}/Dockerfile" \
|
||||
--push \
|
||||
--tag "ghcr.io/${GITHUB_REPOSITORY_OWNER}/infinito-${MATRIX_DISTRO}:${IMAGE_TAG}" \
|
||||
--build-arg "PKGMGR_IMAGE=ghcr.io/kevinveenbirkenbach/pkgmgr-${MATRIX_DISTRO}:stable" \
|
||||
"${nix_arg[@]}" \
|
||||
--cache-from "type=gha,scope=infinito-${MATRIX_DISTRO}" \
|
||||
--cache-to "type=gha,mode=max,scope=infinito-${MATRIX_DISTRO}" \
|
||||
"${BUILD_CONTEXT_DIR}"; then
|
||||
echo "Build & push succeeded on attempt ${attempt}/${max_attempts}."
|
||||
break
|
||||
fi
|
||||
|
||||
if [[ "${attempt}" -ge "${max_attempts}" ]]; then
|
||||
echo "Build & push failed after ${max_attempts} attempts."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Attempt ${attempt} failed. Retrying in ${retry_delay_seconds}s..."
|
||||
sleep "${retry_delay_seconds}"
|
||||
attempt=$((attempt + 1))
|
||||
done
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
: "${PR_NUMBER:?Missing PR_NUMBER}"
|
||||
: "${GITHUB_REPOSITORY:?Missing GITHUB_REPOSITORY}"
|
||||
: "${GITHUB_OUTPUT:?Missing GITHUB_OUTPUT}"
|
||||
|
||||
ref="refs/pull/${PR_NUMBER}/merge"
|
||||
repo_url="https://github.com/${GITHUB_REPOSITORY}.git"
|
||||
sha="${PR_MERGE_SHA:-}"
|
||||
checkout_ref="${ref}"
|
||||
|
||||
if [[ -n "${sha}" ]]; then
|
||||
if [[ ! "${sha}" =~ ^[0-9a-f]{40}$ ]]; then
|
||||
echo "Invalid PR_MERGE_SHA '${sha}', falling back to ${ref}" >&2
|
||||
sha=""
|
||||
else
|
||||
checkout_ref="${sha}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z "${sha}" ]]; then
|
||||
sha="$(git ls-remote "${repo_url}" "${ref}" | awk '{print $1}')"
|
||||
if [[ -z "${sha}" ]]; then
|
||||
echo "Failed to resolve merge SHA for ${ref}" >&2
|
||||
exit 1
|
||||
fi
|
||||
checkout_ref="${sha}"
|
||||
fi
|
||||
|
||||
{
|
||||
echo "checkout_ref=${checkout_ref}"
|
||||
echo "image_tag=ci-${sha}"
|
||||
} >> "${GITHUB_OUTPUT}"
|
||||
|
||||
echo "Resolved fork PR merge ref ${ref} -> ${sha} (checkout_ref=${checkout_ref})"
|
||||
Executable
+70
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
: "${GHCR_NAMESPACE:?Missing GHCR_NAMESPACE}"
|
||||
: "${GHCR_PREFIX:?Missing GHCR_PREFIX}"
|
||||
: "${REPO_ROOT:?Missing REPO_ROOT}"
|
||||
|
||||
max_attempts="${MAX_WAIT_ATTEMPTS:-180}"
|
||||
sleep_seconds="${WAIT_SLEEP_SECONDS:-10}"
|
||||
|
||||
mapfile -t mirror_refs < <(
|
||||
GHCR_NAMESPACE="${GHCR_NAMESPACE}" \
|
||||
GHCR_PREFIX="${GHCR_PREFIX}" \
|
||||
REPO_ROOT="${REPO_ROOT}" \
|
||||
python - <<'PY'
|
||||
import os
|
||||
from pathlib import Path
|
||||
from cli.mirror.providers import GHCRProvider
|
||||
from cli.mirror.util import iter_role_images
|
||||
|
||||
provider = GHCRProvider(
|
||||
os.environ["GHCR_NAMESPACE"],
|
||||
os.environ["GHCR_PREFIX"],
|
||||
)
|
||||
repo_root = Path(os.environ["REPO_ROOT"]).resolve()
|
||||
|
||||
seen = set()
|
||||
for img in iter_role_images(repo_root):
|
||||
ref = f"{provider.image_base(img)}:{img.version}"
|
||||
if ref in seen:
|
||||
continue
|
||||
seen.add(ref)
|
||||
print(ref)
|
||||
PY
|
||||
)
|
||||
|
||||
total="${#mirror_refs[@]}"
|
||||
if [[ "${total}" -eq 0 ]]; then
|
||||
echo "No mirror refs found. Nothing to wait for."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Fork pull_request detected; waiting for mirrored images from pull_request_target."
|
||||
echo "Need ${total} mirror refs."
|
||||
|
||||
missing=()
|
||||
for attempt in $(seq 1 "${max_attempts}"); do
|
||||
missing=()
|
||||
for ref in "${mirror_refs[@]}"; do
|
||||
if ! skopeo inspect "docker://${ref}" >/dev/null 2>&1; then
|
||||
missing+=("${ref}")
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "${#missing[@]}" -eq 0 ]]; then
|
||||
echo "All mirrored images are available."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "[${attempt}/${max_attempts}] Missing ${#missing[@]}/${total} mirror refs. Waiting ${sleep_seconds}s..."
|
||||
echo "Example missing: ${missing[0]}"
|
||||
sleep "${sleep_seconds}"
|
||||
done
|
||||
|
||||
echo "Timed out waiting for mirrored images." >&2
|
||||
echo "Still missing (first 20):" >&2
|
||||
for ref in "${missing[@]:0:20}"; do
|
||||
echo " - ${ref}" >&2
|
||||
done
|
||||
exit 1
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
: "${MATRIX_DISTRO:?Missing MATRIX_DISTRO}"
|
||||
: "${IMAGE_TAG:?Missing IMAGE_TAG}"
|
||||
: "${GITHUB_REPOSITORY_OWNER:?Missing GITHUB_REPOSITORY_OWNER}"
|
||||
|
||||
image="ghcr.io/${GITHUB_REPOSITORY_OWNER}/infinito-${MATRIX_DISTRO}:${IMAGE_TAG}"
|
||||
max_attempts="${MAX_WAIT_ATTEMPTS:-180}"
|
||||
sleep_seconds="${WAIT_SLEEP_SECONDS:-10}"
|
||||
|
||||
echo "Fork pull_request detected; waiting for image built via pull_request_target:"
|
||||
echo " ${image}"
|
||||
|
||||
for attempt in $(seq 1 "${max_attempts}"); do
|
||||
if docker buildx imagetools inspect "${image}" >/dev/null 2>&1; then
|
||||
echo "Image is available: ${image}"
|
||||
exit 0
|
||||
fi
|
||||
echo "[${attempt}/${max_attempts}] Waiting for image..."
|
||||
sleep "${sleep_seconds}"
|
||||
done
|
||||
|
||||
echo "Timed out waiting for prebuilt image: ${image}" >&2
|
||||
exit 1
|
||||
Reference in new issue
Block a user