| Footer.md | ||
| Header.md | ||
| Readme.md | ||
GitLab → GitHub Sync: Checkliste für neue Plugins
Voraussetzungen (einmalig gesetzt, Group-Variablen)
Diese Variablen sind bereits in der GitLab-Gruppe SW-Plugins hinterlegt und gelten automatisch für alle Projekte:
| Key | Beschreibung | Protected | Masked |
|---|---|---|---|
GITHUB_TOKEN |
GitHub Personal Access Token (Fine-grained, Contents: Read & Write) |
✅ | ✅ |
GITHUB_USER |
GitHub Benutzername / Org-Name | ✅ | ❌ |
GITLAB_TOKEN |
GitLab Access Token (read_repository) für Template-Download |
✅ | ✅ |
Hinweis:
GITHUB_USERkann nicht maskiert werden da der Wert zu kurz ist – Protected reicht hier aus.
Checkliste: Neues Plugin einrichten
1. GitHub Repo erstellen
- Neues leeres Repo auf GitHub anlegen
- Name identisch zum GitLab-Repo verwenden (z.B.
WSC_SWPlugin_MeinPlugin) - Kein README, keine .gitignore, keine License beim Erstellen anhaken
2. GitLab Project-Variable anlegen
Settings → CI/CD → Variables → Variable hinzufügen
| Key | Value | Protected | Masked |
|---|---|---|---|
GITHUB_REPO |
z.B. WSC_SWPlugin_MeinPlugin |
✅ | ✅ |
3. Protected Tag-Regel anlegen
Settings → Repository → Protected Tags
| Tag | Allowed to create |
|---|---|
v* |
Maintainers |
Wichtig: Ohne diese Regel bekommen CI-Jobs keinen Zugriff auf die Protected Variables!
4. .gitlab-ci.yml kopieren
Die fertige .gitlab-ci.yml aus einem bestehenden Plugin-Repo als Vorlage kopieren.
Keine Anpassungen nötig – alles läuft über die Variables.
Die vollständige sync-to-github Stage zur Kontrolle:
sync-to-github:
stage: deploy
image: alpine:latest
needs:
- job: build-zip
artifacts: true
before_script:
- apk add --no-cache curl git
rules:
- if: '$CI_COMMIT_TAG'
script: |
YEAR=$(date +%Y)
PLUGIN_NAME=$(basename "$CI_PROJECT_DIR")
ZIP_NAME="${PLUGIN_NAME}.zip"
curl --header "PRIVATE-TOKEN:${GITLAB_TOKEN}" "${CI_API_V4_URL}/projects/csaeum%2Fdev-templates/repository/files/Header.md/raw?ref=main" -o /tmp/header.md
curl --header "PRIVATE-TOKEN:${GITLAB_TOKEN}" "${CI_API_V4_URL}/projects/csaeum%2Fdev-templates/repository/files/Footer.md/raw?ref=main" -o /tmp/footer.md
sed -i "s/\${PLUGIN_NAME}/${GITHUB_REPO}/g" /tmp/header.md
sed -i "s/\${PLUGIN_GRUPPE}/${CI_PROJECT_NAMESPACE}/g" /tmp/header.md
sed -i "s/\${GITHUB_USER}/${GITHUB_USER}/g" /tmp/header.md
sed -i "s/\${GITHUB_REPO}/${GITHUB_REPO}/g" /tmp/header.md
sed -i "s/\${YEAR}/${YEAR}/g" /tmp/footer.md
cat /tmp/header.md README.md /tmp/footer.md > /tmp/README_final.md
cp /tmp/README_final.md README.md
git config user.email "ci@gitlab.local"
git config user.name "GitLab CI"
git fetch --unshallow || true
git remote add github https://oauth2:${GITHUB_TOKEN}@github.com/${GITHUB_USER}/${GITHUB_REPO}.git
git add README.md
git commit -m "chore: add header and footer to README" || true
git push github HEAD:refs/heads/main --follow-tags --force
RELEASE_RESPONSE=$(curl -s \
-H "Authorization: token ${GITHUB_TOKEN}" \
"https://api.github.com/repos/${GITHUB_USER}/${GITHUB_REPO}/releases/tags/${CI_COMMIT_TAG}")
echo "GitHub Response: $RELEASE_RESPONSE"
RELEASE_ID=$(echo "$RELEASE_RESPONSE" | grep -o '"id": *[0-9]*' | head -1 | grep -o '[0-9]*')
if [ -z "$RELEASE_ID" ]; then
RELEASE_RESPONSE=$(curl -s -X POST \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"tag_name\":\"${CI_COMMIT_TAG}\",\"name\":\"${CI_COMMIT_TAG}\",\"body\":\"Release ${CI_COMMIT_TAG}\"}" \
"https://api.github.com/repos/${GITHUB_USER}/${GITHUB_REPO}/releases")
echo "GitHub Create Response: $RELEASE_RESPONSE"
RELEASE_ID=$(echo "$RELEASE_RESPONSE" | grep -o '"id": *[0-9]*' | head -1 | grep -o '[0-9]*')
fi
echo "Release ID: $RELEASE_ID"
if [ -z "$RELEASE_ID" ]; then
echo "ERROR: Release ID konnte nicht ermittelt werden"
exit 1
fi
echo "ZIP Datei vorhanden: $(ls -la ${ZIP_NAME} 2>&1)"
curl -s -X POST \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Content-Type: application/zip" \
--data-binary "@${ZIP_NAME}" \
"https://uploads.github.com/repos/${GITHUB_USER}/${GITHUB_REPO}/releases/${RELEASE_ID}/assets?name=${ZIP_NAME}"
5. README.md im Plugin-Repo pflegen
Die README.md im Plugin-Repo enthält nur den plugin-spezifischen Inhalt (Mitte).
Header und Footer werden automatisch beim Release durch die CI-Pipeline ergänzt.
Aufbau der finalen README auf GitHub:
header.md (aus dev-templates Repo)
+
README.md (plugin-spezifischer Inhalt)
+
footer.md (aus dev-templates Repo)
6. Release erstellen
git tag v1.0.0
git push origin v1.0.0
Hinweis: Tags können nur über die GitLab Web UI gelöscht werden
(Repository → Tags → Papierkorb), da sie als Protected markiert sind.
Header Template (dev-templates/Header.md)
# WSC | ${PLUGIN_GRUPPE} - ${PLUGIN_NAME}
<div align="center">
|  |  |  |
|:---:|:---:|:---:|
</div>
---
Verfügbare Platzhalter im Header:
| Platzhalter | Wert | Quelle |
|---|---|---|
${PLUGIN_NAME} |
Repo-Name z.B. WSC_SWPlugin_MeinPlugin |
Project-Variable GITHUB_REPO |
${PLUGIN_GRUPPE} |
Gruppen-Name z.B. sw-plugins |
Automatisch CI_PROJECT_NAMESPACE |
${GITHUB_USER} |
GitHub Benutzername | Group-Variable GITHUB_USER |
${GITHUB_REPO} |
GitHub Repo-Name | Project-Variable GITHUB_REPO |
Footer Template (dev-templates/Footer.md)
Verfügbare Platzhalter im Footer:
| Platzhalter | Wert | Quelle |
|---|---|---|
${YEAR} |
Aktuelles Jahr z.B. 2026 |
Automatisch date +%Y |
Was passiert beim Release automatisch?
- ✅ Code Style Check
- ✅ PHPStan Analyse
- ✅ SAST Security Scan
- ✅ ZIP-Datei erstellen
- ✅ Header + Footer zur README hinzufügen
- ✅ Code + Tag + README zu GitHub pushen
- ✅ GitHub Release automatisch erstellen
Wichtige GitLab CI Variablen (automatisch)
| Variable | Beschreibung |
|---|---|
CI_PROJECT_NAME |
Repo-Name in Kleinbuchstaben |
CI_PROJECT_NAMESPACE |
Gruppen-Name |
CI_API_V4_URL |
Interne GitLab API URL |
CI_COMMIT_TAG |
Gesetzter Tag – triggert den Deploy-Job |