120 lines
3.7 KiB
YAML
120 lines
3.7 KiB
YAML
name: Mirror source to Forgejo
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
- experimental
|
|
tags:
|
|
- "v[0-9]*"
|
|
- "yams-v[0-9]*"
|
|
workflow_dispatch:
|
|
inputs:
|
|
ref:
|
|
description: Approved branch or release tag to reconcile
|
|
required: true
|
|
default: experimental
|
|
type: string
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: forgejo-source-mirror
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
mirror:
|
|
if: github.repository == 'trvon/yams'
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
steps:
|
|
- name: Check out canonical repository
|
|
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
|
with:
|
|
fetch-depth: 0
|
|
persist-credentials: false
|
|
|
|
- name: Resolve approved source ref
|
|
id: source
|
|
env:
|
|
EVENT_NAME: ${{ github.event_name }}
|
|
EVENT_REF: ${{ github.ref }}
|
|
REQUESTED_REF: ${{ inputs.ref }}
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
if [[ "${EVENT_NAME}" == "workflow_dispatch" ]]; then
|
|
case "${REQUESTED_REF}" in
|
|
main|experimental)
|
|
source_ref="refs/heads/${REQUESTED_REF}"
|
|
;;
|
|
v[0-9]*|yams-v[0-9]*)
|
|
source_ref="refs/tags/${REQUESTED_REF}"
|
|
;;
|
|
*)
|
|
echo "Ref is outside the approved mirror allowlist: ${REQUESTED_REF}" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
else
|
|
source_ref="${EVENT_REF}"
|
|
fi
|
|
|
|
case "${source_ref}" in
|
|
refs/heads/main|refs/heads/experimental|refs/tags/v[0-9]*|refs/tags/yams-v[0-9]*) ;;
|
|
*)
|
|
echo "Resolved ref is outside the approved mirror allowlist: ${source_ref}" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
git fetch --no-tags origin "${source_ref}:refs/mirror/source"
|
|
expected_sha="$(git rev-parse refs/mirror/source)"
|
|
printf 'source_ref=%s\n' "${source_ref}" >>"${GITHUB_OUTPUT}"
|
|
printf 'expected_sha=%s\n' "${expected_sha}" >>"${GITHUB_OUTPUT}"
|
|
|
|
- name: Configure restricted Forgejo SSH identity
|
|
env:
|
|
MIRROR_SSH_KEY: ${{ secrets.FORGEJO_MIRROR_SSH_KEY }}
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
set +x
|
|
test -n "${MIRROR_SSH_KEY}"
|
|
umask 077
|
|
mkdir -p "${HOME}/.ssh"
|
|
printf '%s\n' "${MIRROR_SSH_KEY}" >"${HOME}/.ssh/forgejo_mirror"
|
|
git config core.sshCommand \
|
|
"ssh -i ${HOME}/.ssh/forgejo_mirror -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
|
|
git remote add forgejo ssh://git@git.trevon.dev:2222/trevon/yams.git
|
|
|
|
- name: Push one explicit ref
|
|
env:
|
|
SOURCE_REF: ${{ steps.source.outputs.source_ref }}
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
git push forgejo "refs/mirror/source:${SOURCE_REF}"
|
|
|
|
- name: Verify mirrored SHA
|
|
env:
|
|
SOURCE_REF: ${{ steps.source.outputs.source_ref }}
|
|
EXPECTED_SHA: ${{ steps.source.outputs.expected_sha }}
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
actual_sha="$(git ls-remote --exit-code forgejo "${SOURCE_REF}" | awk 'NR == 1 { print $1 }')"
|
|
if [[ "${actual_sha}" != "${EXPECTED_SHA}" ]]; then
|
|
echo "Forgejo verification failed for ${SOURCE_REF}" >&2
|
|
echo "expected=${EXPECTED_SHA}" >&2
|
|
echo "actual=${actual_sha}" >&2
|
|
exit 1
|
|
fi
|
|
echo "Verified ${SOURCE_REF} at ${EXPECTED_SHA}"
|
|
|
|
- name: Remove temporary key
|
|
if: always()
|
|
shell: bash
|
|
run: rm -f "${HOME}/.ssh/forgejo_mirror"
|