Skip to content

Commit b7f34d4

Browse files
committed
Create mirror.yml
1 parent 11d18aa commit b7f34d4

1 file changed

Lines changed: 104 additions & 0 deletions

File tree

.github/workflows/mirror.yml

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# =============================================================================
2+
# Mirror to Codeberg
3+
# -----------------------------------------------------------------------------
4+
# GitHub bleibt die Quelle der Wahrheit. Bei jedem Push und bei jedem gelöschten
5+
# Branch oder Tag wird der komplette Ref-Stand nach Codeberg gespiegelt.
6+
#
7+
# Der Spiegel ist exakt: mit --prune verschwinden auf Codeberg auch die Branches
8+
# und Tags, die es auf GitHub nicht mehr gibt. Direkt auf Codeberg gepushte
9+
# Commits werden dabei überschrieben. Wer dort etwas beitragen will, macht das
10+
# über GitHub.
11+
#
12+
# EINMALIGE EINRICHTUNG
13+
# 1. Auf Codeberg ein leeres Repository anlegen (ohne README, ohne Lizenz).
14+
# 2. Codeberg → Settings → Applications → Access Token erzeugen.
15+
# Berechtigung: repository → read and write. Nichts weiter.
16+
# 3. In GitHub unter Settings → Secrets and variables → Actions als Secrets
17+
# eintragen:
18+
# CODEBERG_TOKEN → der eben erzeugte Token
19+
# CODEBERG_REPO → z. B. msk-scripts/msk-shop
20+
# CODEBERG_USER → der Codeberg-Benutzername
21+
# 4. Workflow einmal manuell über "Run workflow" starten, danach läuft er
22+
# bei jedem Push von allein.
23+
#
24+
# Repo-Name und Benutzername sind eigentlich keine Geheimnisse und wären als
25+
# Variables besser aufgehoben. Sie liegen hier trotzdem als Secrets, weil der
26+
# secrets-Kontext im Job-Level-`if` nicht lesbar ist und die Konfiguration so an
27+
# einer einzigen Stelle bleibt. Der einzige Nebeneffekt: GitHub maskiert beide
28+
# Werte in der Log-Ausgabe.
29+
# =============================================================================
30+
31+
name: Mirror to Codeberg
32+
33+
on:
34+
push:
35+
branches: ["**"]
36+
tags: ["**"]
37+
delete:
38+
workflow_dispatch:
39+
40+
# Nur lesen. Der Workflow schreibt ausschließlich auf das fremde Remote.
41+
permissions:
42+
contents: read
43+
44+
# Zwei parallele Mirror-Läufe würden sich gegenseitig überholen und könnten
45+
# einen älteren Stand als letztes schreiben. Deshalb strikt seriell, und ein
46+
# laufender Job wird NICHT abgebrochen.
47+
concurrency:
48+
group: mirror-codeberg
49+
cancel-in-progress: false
50+
51+
jobs:
52+
mirror:
53+
name: Push to Codeberg
54+
runs-on: ubuntu-latest
55+
# In Forks nicht spiegeln. Ob die Secrets gesetzt sind, prüft der Step unten,
56+
# der secrets-Kontext ist auf dieser Ebene nicht lesbar.
57+
if: github.repository_owner == 'MSK-Scripts'
58+
59+
steps:
60+
- name: Checkout (vollständige History, alle Refs)
61+
uses: actions/checkout@v4
62+
with:
63+
# Ein Mirror braucht die ganze History, nicht nur den letzten Commit.
64+
fetch-depth: 0
65+
66+
- name: Push branches and tags to Codeberg
67+
env:
68+
CODEBERG_TOKEN: ${{ secrets.CODEBERG_TOKEN }}
69+
CODEBERG_USER: ${{ secrets.CODEBERG_USER }}
70+
CODEBERG_REPO: ${{ secrets.CODEBERG_REPO }}
71+
run: |
72+
set -euo pipefail
73+
74+
if [ -z "${CODEBERG_TOKEN:-}" ] || [ -z "${CODEBERG_USER:-}" ] || [ -z "${CODEBERG_REPO:-}" ]; then
75+
echo "::error::Die Secrets CODEBERG_TOKEN, CODEBERG_USER und CODEBERG_REPO müssen gesetzt sein."
76+
exit 1
77+
fi
78+
79+
# Alle Remote-Refs von GitHub holen, inklusive gelöschter (--prune),
80+
# damit der Spiegel auch Löschungen nachvollzieht.
81+
git fetch --prune --prune-tags --tags origin
82+
83+
# refs/remotes/origin/HEAD ist ein symbolischer Ref auf den Default-
84+
# Branch. Ohne dieses Löschen matcht er die Refspec unten mit und landet
85+
# auf Codeberg als echter Branch namens "HEAD", der dort jeden Ref-Namen
86+
# mehrdeutig macht.
87+
#
88+
# Bewusst `git remote set-head --delete` und NICHT `git update-ref -d`:
89+
# update-ref dereferenziert symbolische Refs und würde damit den
90+
# Default-Branch selbst löschen statt den Zeiger darauf.
91+
git remote set-head origin --delete || true
92+
93+
# Die Token-URL steht nur in dieser Variable, nie in der Kommandozeile,
94+
# damit sie nicht im Prozess-Log auftaucht. GitHub maskiert das Secret
95+
# zusätzlich in der Ausgabe.
96+
REMOTE="https://${CODEBERG_USER}:${CODEBERG_TOKEN}@codeberg.org/${CODEBERG_REPO}.git"
97+
98+
# refs/remotes/origin/* statt refs/heads/*: der Checkout legt lokal nur
99+
# einen Branch an, die anderen existieren nur als Remote-Tracking-Refs.
100+
git push --force --prune "$REMOTE" \
101+
"refs/remotes/origin/*:refs/heads/*" \
102+
"refs/tags/*:refs/tags/*"
103+
104+
echo "Spiegel aktualisiert: codeberg.org/${CODEBERG_REPO}"

0 commit comments

Comments
 (0)