Compare commits
31
Commits
dev
...
25189f800b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25189f800b | ||
|
|
2b8b8260b1 | ||
|
|
a2f1c987f8 | ||
|
|
2be18e6fd2 | ||
|
|
0970dbefae | ||
|
|
246e5e85d9 | ||
|
|
694b13f01c | ||
|
|
8786971d24 | ||
|
|
c20986cf6c | ||
|
|
d16175d16b | ||
|
|
516ff1a0fa | ||
|
|
901e9c94f4 | ||
|
|
835ca055c2 | ||
|
|
b5fbadd560 | ||
|
|
b6ed37f3b4 | ||
|
|
ab19e63e94 | ||
|
|
0609225281 | ||
|
|
9afb1e0794 | ||
|
|
5f0b994768 | ||
|
|
0be6135e52 | ||
|
|
ec21aa2b9e | ||
|
|
b27c3e257b | ||
|
|
284ee7462e | ||
|
|
4c6c8df7af | ||
|
|
05d51481d7 | ||
|
|
d5a99d0f88 | ||
|
|
b6a8bc1f61 | ||
|
|
eaf568bb9e | ||
|
|
d5d9a5d07c | ||
|
|
a8870999a7 | ||
|
|
9c795a58ee |
No files matched your search
@@ -8,6 +8,10 @@ on:
|
|||||||
- cron: '0 5 * * 0'
|
- cron: '0 5 * * 0'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release-and-build:
|
release-and-build:
|
||||||
runs-on: buildx-multiarch
|
runs-on: buildx-multiarch
|
||||||
@@ -16,6 +20,7 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
|
token: ${{ secrets.RUNNER_TOKEN }}
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Prepare Environment and Read Config
|
- name: Prepare Environment and Read Config
|
||||||
@@ -59,8 +64,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Login to Gitea Registry
|
- name: Login to Gitea Registry
|
||||||
run: |
|
run: |
|
||||||
echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login \
|
echo "${{ secrets.RUNNER_TOKEN }}" | docker login git.pi-farm.de -u "${{ gitea.actor }}" --password-stdin
|
||||||
git.pi-farm.de -u ${{ secrets.REGISTRY_USER }} --password-stdin
|
|
||||||
|
|
||||||
- name: Check for Real Changes
|
- name: Check for Real Changes
|
||||||
id: check_changes
|
id: check_changes
|
||||||
@@ -125,6 +129,7 @@ jobs:
|
|||||||
ARGS_HASH=${{ steps.prep.outputs.build_args_hash }}
|
ARGS_HASH=${{ steps.prep.outputs.build_args_hash }}
|
||||||
BASE=${{ steps.prep.outputs.base_image }}
|
BASE=${{ steps.prep.outputs.base_image }}
|
||||||
REPO_PURE=${{ steps.prep.outputs.repo_pure }}
|
REPO_PURE=${{ steps.prep.outputs.repo_pure }}
|
||||||
|
DOCKERHUB_REPO="${{ secrets.DOCKERHUB_USERNAME }}/$REPO_PURE"
|
||||||
|
|
||||||
set -a
|
set -a
|
||||||
source <(grep -v '^#' buildargs.env | sed 's/\r$//')
|
source <(grep -v '^#' buildargs.env | sed 's/\r$//')
|
||||||
@@ -138,14 +143,26 @@ jobs:
|
|||||||
|
|
||||||
BASE_SHA=$(docker buildx imagetools inspect $BASE --format '{{json .Manifest.Digest}}' 2>/dev/null | tr -d '"' || echo "unknown")
|
BASE_SHA=$(docker buildx imagetools inspect $BASE --format '{{json .Manifest.Digest}}' 2>/dev/null | tr -d '"' || echo "unknown")
|
||||||
|
|
||||||
docker buildx build "${DOCKER_ARGS[@]}" -t "$IMAGE_GITEA:tmp-amd64" \
|
# Bereite die Tags für den initialen Build vor (Gitea immer, Docker Hub optional)
|
||||||
|
AMD_TAGS=("-t" "$IMAGE_GITEA:tmp-amd64")
|
||||||
|
ARM_TAGS=("-t" "$IMAGE_GITEA:tmp-arm64")
|
||||||
|
|
||||||
|
if [[ "$PUSH" == *"dockerhub"* ]]; then
|
||||||
|
AMD_TAGS+=("-t" "$DOCKERHUB_REPO:tmp-amd64")
|
||||||
|
ARM_TAGS+=("-t" "$DOCKERHUB_REPO:tmp-arm64")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build AMD64 & Push zu allen Zielen
|
||||||
|
docker buildx build "${DOCKER_ARGS[@]}" "${AMD_TAGS[@]}" \
|
||||||
--pull --platform linux/amd64 -f Dockerfile \
|
--pull --platform linux/amd64 -f Dockerfile \
|
||||||
--label "pi_farm.base_digest=$BASE_SHA" --label "pi_farm.args_hash=$ARGS_HASH" --push .
|
--label "pi_farm.base_digest=$BASE_SHA" --label "pi_farm.args_hash=$ARGS_HASH" --push .
|
||||||
|
|
||||||
docker buildx build "${DOCKER_ARGS[@]}" -t "$IMAGE_GITEA:tmp-arm64" \
|
# Build ARM64 & Push zu allen Zielen
|
||||||
|
docker buildx build "${DOCKER_ARGS[@]}" "${ARM_TAGS[@]}" \
|
||||||
--pull --platform linux/arm64 -f Dockerfile.aarch64 \
|
--pull --platform linux/arm64 -f Dockerfile.aarch64 \
|
||||||
--label "pi_farm.base_digest=$BASE_SHA" --label "pi_farm.args_hash=$ARGS_HASH" --push .
|
--label "pi_farm.base_digest=$BASE_SHA" --label "pi_farm.args_hash=$ARGS_HASH" --push .
|
||||||
|
|
||||||
|
# 1. Manifest auf Gitea erstellen (aus Gitea Temp-Tags)
|
||||||
GITEA_MANIFEST_TAGS=("-t" "$IMAGE_GITEA:$TAG")
|
GITEA_MANIFEST_TAGS=("-t" "$IMAGE_GITEA:$TAG")
|
||||||
if [[ "$BUILD_TAG_LATEST" == "y" ]]; then
|
if [[ "$BUILD_TAG_LATEST" == "y" ]]; then
|
||||||
GITEA_MANIFEST_TAGS+=("-t" "$IMAGE_GITEA:latest")
|
GITEA_MANIFEST_TAGS+=("-t" "$IMAGE_GITEA:latest")
|
||||||
@@ -155,232 +172,258 @@ jobs:
|
|||||||
--annotation "index:pi_farm.base_digest=$BASE_SHA" --annotation "index:pi_farm.args_hash=$ARGS_HASH" \
|
--annotation "index:pi_farm.base_digest=$BASE_SHA" --annotation "index:pi_farm.args_hash=$ARGS_HASH" \
|
||||||
"${GITEA_MANIFEST_TAGS[@]}" $IMAGE_GITEA:tmp-amd64 $IMAGE_GITEA:tmp-arm64
|
"${GITEA_MANIFEST_TAGS[@]}" $IMAGE_GITEA:tmp-amd64 $IMAGE_GITEA:tmp-arm64
|
||||||
|
|
||||||
|
# 2. Manifest auf Docker Hub erstellen (aus Docker Hub Temp-Tags!)
|
||||||
if [[ "$PUSH" == *"dockerhub"* ]]; then
|
if [[ "$PUSH" == *"dockerhub"* ]]; then
|
||||||
DOCKERHUB_REPO="${{ secrets.DOCKERHUB_USERNAME }}/$REPO_PURE"
|
|
||||||
DH_MANIFEST_TAGS=("-t" "$DOCKERHUB_REPO:$TAG")
|
DH_MANIFEST_TAGS=("-t" "$DOCKERHUB_REPO:$TAG")
|
||||||
if [[ "$BUILD_TAG_LATEST" == "y" ]]; then
|
if [[ "$BUILD_TAG_LATEST" == "y" ]]; then
|
||||||
DH_MANIFEST_TAGS+=("-t" "$DOCKERHUB_REPO:latest")
|
DH_MANIFEST_TAGS+=("-t" "$DOCKERHUB_REPO:latest")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# WICHTIG: Hier werden jetzt als Quelle die Docker Hub Temp-Tags genutzt!
|
||||||
docker buildx imagetools create \
|
docker buildx imagetools create \
|
||||||
--annotation "index:pi_farm.base_digest=$BASE_SHA" --annotation "index:pi_farm.args_hash=$ARGS_HASH" \
|
--annotation "index:pi_farm.base_digest=$BASE_SHA" --annotation "index:pi_farm.args_hash=$ARGS_HASH" \
|
||||||
"${DH_MANIFEST_TAGS[@]}" $IMAGE_GITEA:tmp-amd64 $IMAGE_GITEA:tmp-arm64
|
"${DH_MANIFEST_TAGS[@]}" $DOCKERHUB_REPO:tmp-amd64 $DOCKERHUB_REPO:tmp-arm64
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Update Documentation and Compose
|
- name: Update Documentation and Compose
|
||||||
id: update_doc
|
id: update_doc
|
||||||
if: steps.check_changes.outputs.should_build == 'true'
|
if: steps.check_changes.outputs.should_build == 'true'
|
||||||
run: |
|
run: |
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
export TZ=Europe/Berlin
|
export TZ=Europe/Berlin
|
||||||
CURRENT_TIME=$(date '+%d.%m.%Y %H:%M')
|
CURRENT_TIME=$(date '+%d.%m.%Y %H:%M')
|
||||||
BUILD_TAG="${{ steps.prep.outputs.docker_tag }}"
|
BUILD_TAG="${{ steps.prep.outputs.docker_tag }}"
|
||||||
FULL_URL="${{ steps.prep.outputs.image_name }}"
|
FULL_URL="${{ steps.prep.outputs.image_name }}"
|
||||||
REPO_PURE="${{ steps.prep.outputs.repo_pure }}"
|
REPO_PURE="${{ steps.prep.outputs.repo_pure }}"
|
||||||
BASE_IMAGE="${{ steps.prep.outputs.base_image }}"
|
BASE_IMAGE="${{ steps.prep.outputs.base_image }}"
|
||||||
|
|
||||||
if [ ! -f "buildargs.env" ]; then echo "❌ buildargs.env missing!"; exit 1; fi
|
if [ ! -f "buildargs.env" ]; then echo "❌ buildargs.env missing!"; exit 1; fi
|
||||||
|
|
||||||
grep -v '^#' buildargs.env | sed 's/\r$//' > cleaned_env.sh
|
grep -v '^#' buildargs.env | sed 's/\r$//' > cleaned_env.sh
|
||||||
set -a
|
set -a
|
||||||
source ./cleaned_env.sh
|
source ./cleaned_env.sh
|
||||||
set +a
|
set +a
|
||||||
|
|
||||||
if [ -f "Dockerfile.aarch64" ]; then ARM_STATUS="✅ Active"; else ARM_STATUS="❌ Not supported"; fi
|
if [ -f "Dockerfile.aarch64" ]; then ARM_STATUS="✅ Active"; else ARM_STATUS="❌ Not supported"; fi
|
||||||
|
|
||||||
cat << 'EOF' > commit_msg.txt
|
cat << 'EOF' > commit_msg.txt
|
||||||
${{ gitea.event.head_commit.message }}
|
${{ gitea.event.head_commit.message }}
|
||||||
EOF
|
EOF
|
||||||
COMMIT_MSG=$(sed 's/\[skip ci\]//g' commit_msg.txt | xargs)
|
COMMIT_MSG=$(sed 's/\[skip ci\]//g' commit_msg.txt | xargs)
|
||||||
|
|
||||||
wget -q https://git.pi-farm.de/pi-farm/templates/raw/branch/main/README.template -O README.template || echo "Warnung: README Template fehlt"
|
# 1. Authentifizierter Download der Templates via curl (-f bricht bei HTTP-Fehlern ab)
|
||||||
wget -q https://git.pi-farm.de/pi-farm/templates/raw/branch/main/docker-compose.template -O docker-compose.template || echo "Warnung: Compose Template fehlt"
|
TOKEN="${{ secrets.RUNNER_TOKEN }}"
|
||||||
|
curl -sSLf -H "Authorization: token $TOKEN" \
|
||||||
NEW_ROW="| **$BUILD_TAG** | $CURRENT_TIME | $COMMIT_MSG ✅ |"
|
"https://git.pi-farm.de/pi-farm/templates/raw/branch/main/README.template" \
|
||||||
if [ -f "VERSION.history" ]; then
|
-o README.template || echo "Warnung: README Template konnte nicht geladen werden"
|
||||||
grep -v "| **$BUILD_TAG** |" VERSION.history > VERSION.history.tmp || true
|
|
||||||
echo "$NEW_ROW" > VERSION.history
|
curl -sSLf -H "Authorization: token $TOKEN" \
|
||||||
cat VERSION.history.tmp >> VERSION.history
|
"https://git.pi-farm.de/pi-farm/templates/raw/branch/main/docker-compose.template" \
|
||||||
rm VERSION.history.tmp
|
-o docker-compose.template || echo "Warnung: Compose Template konnte nicht geladen werden"
|
||||||
else
|
|
||||||
echo "$NEW_ROW" > VERSION.history
|
# 2. Sicherheitsprüfung: Falls Gitea trotz -f eine HTML-Login-Seite ausgibt, Datei sofort verwerfen
|
||||||
fi
|
for t_file in README.template docker-compose.template; do
|
||||||
HISTORY_CONTENT=$(cat VERSION.history)
|
if [ -f "$t_file" ] && grep -qi "<!DOCTYPE html>" "$t_file"; then
|
||||||
|
echo "❌ FEHLER: $t_file ist eine HTML-Loginseite! Download verworfen."
|
||||||
ENV_BLOCK_CONTENT=""
|
rm -f "$t_file"
|
||||||
env_vars=$(grep '^ENV_' buildargs.env | grep -v '^#' | tr -d '\r' || true)
|
|
||||||
if [ -n "$env_vars" ]; then
|
|
||||||
ENV_BLOCK_CONTENT=" environment:\n"
|
|
||||||
while read -r line; do
|
|
||||||
[ -z "$line" ] && continue
|
|
||||||
key=$(echo "$line" | cut -d= -f1); val=$(echo "$line" | cut -d= -f2-); clean_key=${key#ENV_}
|
|
||||||
ENV_BLOCK_CONTENT="${ENV_BLOCK_CONTENT} - ${clean_key}=${val}\n"
|
|
||||||
done <<< "$env_vars"
|
|
||||||
fi
|
|
||||||
|
|
||||||
PORTS_BLOCK_CONTENT=""
|
|
||||||
port_vars=$(grep '^PORT_' buildargs.env | grep -v '^#' | tr -d '\r' || true)
|
|
||||||
if [ -n "$port_vars" ]; then
|
|
||||||
PORTS_BLOCK_CONTENT=" ports:\n"
|
|
||||||
while read -r line; do
|
|
||||||
[ -z "$line" ] && continue
|
|
||||||
val=$(echo "$line" | cut -d= -f2-); PORTS_BLOCK_CONTENT="${PORTS_BLOCK_CONTENT} - ${val}\n"
|
|
||||||
done <<< "$port_vars"
|
|
||||||
fi
|
|
||||||
|
|
||||||
VOL_BLOCK_CONTENT=""
|
|
||||||
vol_vars=$(grep '^VOL_' buildargs.env | grep -v '^#' | tr -d '\r' || true)
|
|
||||||
if [ -n "$vol_vars" ]; then
|
|
||||||
VOL_BLOCK_CONTENT=" volumes:\n"
|
|
||||||
while read -r line; do
|
|
||||||
[ -z "$line" ] && continue
|
|
||||||
val=$(echo "$line" | cut -d= -f2-); VOL_BLOCK_CONTENT="${VOL_BLOCK_CONTENT} - ${val}\n"
|
|
||||||
done <<< "$vol_vars"
|
|
||||||
fi
|
|
||||||
|
|
||||||
{
|
|
||||||
echo "docker run -d \\"
|
|
||||||
echo " --name $REPO_PURE \\"
|
|
||||||
echo " --restart unless-stopped \\"
|
|
||||||
|
|
||||||
all_params=$(grep -E '^(PORT_|ENV_|VOL_)' buildargs.env | grep -v '^#' | sed 's/\r$//' || true)
|
|
||||||
if [ -n "$all_params" ]; then
|
|
||||||
while read -r line; do
|
|
||||||
[ -z "$line" ] && continue
|
|
||||||
if [[ "$line" =~ ^PORT_ ]]; then
|
|
||||||
val=$(echo "$line" | cut -d= -f2-)
|
|
||||||
echo " -p ${val} \\"
|
|
||||||
elif [[ "$line" =~ ^ENV_ ]]; then
|
|
||||||
key=$(echo "$line" | cut -d= -f1); clean_key=${key#ENV_}; val=$(echo "$line" | cut -d= -f2-)
|
|
||||||
echo " -e ${clean_key}=${val} \\"
|
|
||||||
elif [[ "$line" =~ ^VOL_ ]]; then
|
|
||||||
val=$(echo "$line" | cut -d= -f2-)
|
|
||||||
echo " -v ${val} \\"
|
|
||||||
fi
|
fi
|
||||||
done <<< "$all_params"
|
done
|
||||||
fi
|
|
||||||
echo " $FULL_URL:$BUILD_TAG"
|
NEW_ROW="| **$BUILD_TAG** | $CURRENT_TIME | $COMMIT_MSG ✅ |"
|
||||||
} > docker_run_block.txt
|
if [ -f "VERSION.history" ]; then
|
||||||
|
grep -v "| **$BUILD_TAG** |" VERSION.history > VERSION.history.tmp || true
|
||||||
DOCKERHUB_LINK_CONTENT=""
|
echo "$NEW_ROW" > VERSION.history
|
||||||
if [[ "${{ steps.prep.outputs.push_targets }}" == *"dockerhub"* ]]; then
|
cat VERSION.history.tmp >> VERSION.history
|
||||||
DH_USER="${{ secrets.DOCKERHUB_USERNAME }}"
|
rm VERSION.history.tmp
|
||||||
DOCKERHUB_LINK_CONTENT="[](https://hub.docker.com/r/${DH_USER}/${REPO_PURE})"
|
else
|
||||||
fi
|
echo "$NEW_ROW" > VERSION.history
|
||||||
|
fi
|
||||||
process_template() {
|
HISTORY_CONTENT=$(cat VERSION.history)
|
||||||
local template=$1; local output=$2
|
|
||||||
[ ! -f "$template" ] && return
|
ENV_BLOCK_CONTENT=""
|
||||||
cp "$template" "$output"
|
env_vars=$(grep '^ENV_' buildargs.env | grep -v '^#' | tr -d '\r' || true)
|
||||||
|
if [ -n "$env_vars" ]; then
|
||||||
|
ENV_BLOCK_CONTENT=" environment:\n"
|
||||||
|
while read -r line; do
|
||||||
|
[ -z "$line" ] && continue
|
||||||
|
key=$(echo "$line" | cut -d= -f1); val=$(echo "$line" | cut -d= -f2-); clean_key=${key#ENV_}
|
||||||
|
ENV_BLOCK_CONTENT="${ENV_BLOCK_CONTENT} - ${clean_key}=${val}\n"
|
||||||
|
done <<< "$env_vars"
|
||||||
|
fi
|
||||||
|
|
||||||
|
PORTS_BLOCK_CONTENT=""
|
||||||
|
port_vars=$(grep '^PORT_' buildargs.env | grep -v '^#' | tr -d '\r' || true)
|
||||||
|
if [ -n "$port_vars" ]; then
|
||||||
|
PORTS_BLOCK_CONTENT=" ports:\n"
|
||||||
|
while read -r line; do
|
||||||
|
[ -z "$line" ] && continue
|
||||||
|
val=$(echo "$line" | cut -d= -f2-); PORTS_BLOCK_CONTENT="${PORTS_BLOCK_CONTENT} - ${val}\n"
|
||||||
|
done <<< "$port_vars"
|
||||||
|
fi
|
||||||
|
|
||||||
|
VOL_BLOCK_CONTENT=""
|
||||||
|
vol_vars=$(grep '^VOL_' buildargs.env | grep -v '^#' | tr -d '\r' || true)
|
||||||
|
if [ -n "$vol_vars" ]; then
|
||||||
|
VOL_BLOCK_CONTENT=" volumes:\n"
|
||||||
|
while read -r line; do
|
||||||
|
[ -z "$line" ] && continue
|
||||||
|
val=$(echo "$line" | cut -d= -f2-); VOL_BLOCK_CONTENT="${VOL_BLOCK_CONTENT} - ${val}\n"
|
||||||
|
done <<< "$vol_vars"
|
||||||
|
fi
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "docker run -d \\"
|
||||||
|
echo " --name $REPO_PURE \\"
|
||||||
|
echo " --restart unless-stopped \\"
|
||||||
|
|
||||||
|
all_params=$(grep -E '^(PORT_|ENV_|VOL_)' buildargs.env | grep -v '^#' | sed 's/\r$//' || true)
|
||||||
|
if [ -n "$all_params" ]; then
|
||||||
|
while read -r line; do
|
||||||
|
[ -z "$line" ] && continue
|
||||||
|
if [[ "$line" =~ ^PORT_ ]]; then
|
||||||
|
val=$(echo "$line" | cut -d= -f2-)
|
||||||
|
echo " -p ${val} \\"
|
||||||
|
elif [[ "$line" =~ ^ENV_ ]]; then
|
||||||
|
key=$(echo "$line" | cut -d= -f1); clean_key=${key#ENV_}; val=$(echo "$line" | cut -d= -f2-)
|
||||||
|
echo " -e ${clean_key}=${val} \\"
|
||||||
|
elif [[ "$line" =~ ^VOL_ ]]; then
|
||||||
|
val=$(echo "$line" | cut -d= -f2-)
|
||||||
|
echo " -v ${val} \\"
|
||||||
|
fi
|
||||||
|
done <<< "$all_params"
|
||||||
|
fi
|
||||||
|
echo " $FULL_URL:$BUILD_TAG"
|
||||||
|
} > docker_run_block.txt
|
||||||
|
|
||||||
|
DOCKERHUB_LINK_CONTENT=""
|
||||||
|
if [[ "${{ steps.prep.outputs.push_targets }}" == *"dockerhub"* ]]; then
|
||||||
|
DH_USER="${{ secrets.DOCKERHUB_USERNAME }}"
|
||||||
|
DOCKERHUB_LINK_CONTENT="[](https://hub.docker.com/r/${DH_USER}/${REPO_PURE})"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Template-Verarbeitung via Python (verhindert awk-Abstürze bei Zeilenumbrüchen)
|
||||||
|
process_template() {
|
||||||
|
local template=$1; local output=$2
|
||||||
|
[ ! -f "$template" ] && return
|
||||||
|
cp "$template" "$output"
|
||||||
|
|
||||||
|
export REPO_PURE FULL_URL BUILD_TAG BASE_IMAGE ARM_STATUS CURRENT_TIME \
|
||||||
|
HISTORY_CONTENT DOCKERHUB_LINK_CONTENT ENV_BLOCK_CONTENT \
|
||||||
|
PORTS_BLOCK_CONTENT VOL_BLOCK_CONTENT DESCRIPTION
|
||||||
|
|
||||||
|
python3 -c '
|
||||||
|
import os, sys
|
||||||
|
|
||||||
|
output = sys.argv[1]
|
||||||
|
|
||||||
|
with open(output, "r", encoding="utf-8") as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
content = content.replace("__REPO_NAME__", os.environ.get("REPO_PURE", ""))
|
||||||
|
content = content.replace("__FULL_URL__", os.environ.get("FULL_URL", ""))
|
||||||
|
content = content.replace("__BUILD_TAG__", os.environ.get("BUILD_TAG", ""))
|
||||||
|
content = content.replace("__BASE_IMAGE__", os.environ.get("BASE_IMAGE", ""))
|
||||||
|
content = content.replace("__ARM_STATUS__", os.environ.get("ARM_STATUS", ""))
|
||||||
|
content = content.replace("__CURRENT_DATE__", os.environ.get("CURRENT_TIME", ""))
|
||||||
|
content = content.replace("__HISTORY_CONTENT__", os.environ.get("HISTORY_CONTENT", ""))
|
||||||
|
content = content.replace("__DOCKERHUB_LINK__", os.environ.get("DOCKERHUB_LINK_CONTENT", ""))
|
||||||
|
content = content.replace("__ENV_BLOCK__", os.environ.get("ENV_BLOCK_CONTENT", "").replace("\\n", "\n"))
|
||||||
|
content = content.replace("__PORTS_BLOCK__", os.environ.get("PORTS_BLOCK_CONTENT", "").replace("\\n", "\n"))
|
||||||
|
content = content.replace("__VOL_BLOCK__", os.environ.get("VOL_BLOCK_CONTENT", "").replace("\\n", "\n"))
|
||||||
|
content = content.replace("__DESCRIPTION__", os.environ.get("DESCRIPTION", "Keine Beschreibung."))
|
||||||
|
|
||||||
sed -i "s|__REPO_NAME__|$REPO_PURE|g" "$output"
|
if "__DOCKER_RUN__" in content and os.path.exists("docker_run_block.txt"):
|
||||||
sed -i "s|__FULL_URL__|$FULL_URL|g" "$output"
|
with open("docker_run_block.txt", "r", encoding="utf-8") as f:
|
||||||
sed -i "s|__BUILD_TAG__|$BUILD_TAG|g" "$output"
|
content = content.replace("__DOCKER_RUN__", f.read())
|
||||||
sed -i "s|__BASE_IMAGE__|$BASE_IMAGE|g" "$output"
|
|
||||||
sed -i "s|__ARM_STATUS__|$ARM_STATUS|g" "$output"
|
|
||||||
sed -i "s|__CURRENT_DATE__|$CURRENT_TIME|g" "$output"
|
|
||||||
|
|
||||||
awk -v r="$HISTORY_CONTENT" '{gsub(/__HISTORY_CONTENT__/, r)}1' "$output" > "$output.tmp" && mv "$output.tmp" "$output"
|
if "__COMPOSE_BLOCK__" in content and os.path.exists("docker-compose.yml"):
|
||||||
awk -v r="$DOCKERHUB_LINK_CONTENT" '{gsub(/__DOCKERHUB_LINK__/, r)}1' "$output" > "$output.tmp" && mv "$output.tmp" "$output"
|
with open("docker-compose.yml", "r", encoding="utf-8") as f:
|
||||||
|
content = content.replace("__COMPOSE_BLOCK__", f.read())
|
||||||
if grep -q "__DOCKER_RUN__" "$output" && [ -f "docker_run_block.txt" ]; then
|
|
||||||
sed -e '/__DOCKER_RUN__/{r docker_run_block.txt' -e 'd;}' "$output" > "$output.tmp" && mv "$output.tmp" "$output"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if grep -q "__COMPOSE_BLOCK__" "$output" && [ -f "docker-compose.yml" ]; then
|
with open(output, "w", encoding="utf-8") as f:
|
||||||
sed -e '/__COMPOSE_BLOCK__/{r docker-compose.yml' -e 'd;}' "$output" > "$output.tmp" && mv "$output.tmp" "$output"
|
f.write(content)
|
||||||
fi
|
' "$output"
|
||||||
|
}
|
||||||
|
|
||||||
if grep -q "__ENV_BLOCK__" "$output"; then
|
process_template "docker-compose.template" "docker-compose.yml"
|
||||||
awk -v r="$(echo -e "$ENV_BLOCK_CONTENT")" '{gsub(/__ENV_BLOCK__/, r)}1' "$output" > "$output.tmp" && mv "$output.tmp" "$output"
|
process_template "README.template" "README.md"
|
||||||
fi
|
|
||||||
awk -v r="$(echo -e "$PORTS_BLOCK_CONTENT")" '{gsub(/__PORTS_BLOCK__/, r)}1' "$output" > "$output.tmp" && mv "$output.tmp" "$output"
|
echo "FINAL_MSG=$COMMIT_MSG" >> $GITHUB_ENV
|
||||||
awk -v r="$(echo -e "$VOL_BLOCK_CONTENT")" '{gsub(/__VOL_BLOCK__/, r)}1' "$output" > "$output.tmp" && mv "$output.tmp" "$output"
|
echo "DESCRIPTION<<EOF" >> $GITHUB_ENV
|
||||||
|
echo -e "$DESCRIPTION" >> $GITHUB_ENV
|
||||||
|
echo "EOF" >> $GITHUB_ENV
|
||||||
|
|
||||||
if grep -q "__DESCRIPTION__" "$output"; then
|
- name: Push README to Docker Hub
|
||||||
awk -v r="$(echo -e "${DESCRIPTION:-Keine Beschreibung.}")" '{gsub(/__DESCRIPTION__/, r)}1' "$output" > "$output.tmp" && mv "$output.tmp" "$output"
|
if: steps.check_changes.outputs.should_build == 'true' && contains(steps.prep.outputs.push_targets, 'dockerhub')
|
||||||
fi
|
run: |
|
||||||
}
|
if ! command -v jq &> /dev/null; then
|
||||||
|
apt-get update && apt-get install -y jq || apk add --no-cache jq || true
|
||||||
process_template "docker-compose.template" "docker-compose.yml"
|
fi
|
||||||
process_template "README.template" "README.md"
|
|
||||||
|
echo "🚀 Starting update README on Docker Hub..."
|
||||||
echo "FINAL_MSG=$COMMIT_MSG" >> $GITHUB_ENV
|
|
||||||
echo "DESCRIPTION<<EOF" >> $GITHUB_ENV
|
TOKEN=$(curl -s -X POST "https://hub.docker.com/v2/users/login/" \
|
||||||
echo -e "$DESCRIPTION" >> $GITHUB_ENV
|
-H "Content-Type: application/json" \
|
||||||
echo "EOF" >> $GITHUB_ENV
|
-d "{\"username\": \"${{ secrets.DOCKERHUB_USERNAME }}\", \"password\": \"${{ secrets.DOCKERHUB_TOKEN }}\"}" | jq -r .token)
|
||||||
|
|
||||||
- name: Push README to Docker Hub
|
if [ "$TOKEN" == "null" ] || [ -z "$TOKEN" ]; then
|
||||||
if: steps.check_changes.outputs.should_build == 'true' && contains(steps.prep.outputs.push_targets, 'dockerhub')
|
echo "❌ Error: No login-token available. Check your credentials!"
|
||||||
run: |
|
exit 1
|
||||||
if ! command -v jq &> /dev/null; then
|
fi
|
||||||
apt-get update && apt-get install -y jq || apk add --no-cache jq || true
|
|
||||||
fi
|
REPO_PURE="${{ steps.prep.outputs.repo_pure }}"
|
||||||
|
DH_USER="${{ secrets.DOCKERHUB_USERNAME }}"
|
||||||
echo "🚀 Starting update README on Docker Hub..."
|
|
||||||
|
SHORT_DESC=$(echo -e "${{ env.DESCRIPTION }}" | head -n 1 | cut -c 1-100)
|
||||||
TOKEN=$(curl -s -X POST "https://hub.docker.com/v2/users/login/" \
|
[ -z "$SHORT_DESC" ] && SHORT_DESC="Docker Image for $REPO_PURE"
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "{\"username\": \"${{ secrets.DOCKERHUB_USERNAME }}\", \"password\": \"${{ secrets.DOCKERHUB_TOKEN }}\"}" | jq -r .token)
|
echo "📦 Processing README.md (${REPO_PURE})..."
|
||||||
|
|
||||||
if [ "$TOKEN" == "null" ] || [ -z "$TOKEN" ]; then
|
jq -n \
|
||||||
echo "❌ Error: No login-token available. Check your credentials!"
|
--arg desc "$SHORT_DESC" \
|
||||||
exit 1
|
--rawfile full_desc README.md \
|
||||||
fi
|
'{description: $desc, full_description: $full_desc}' > payload.json
|
||||||
|
|
||||||
REPO_PURE="${{ steps.prep.outputs.repo_pure }}"
|
echo "📤 Sending data to Docker Hub API..."
|
||||||
DH_USER="${{ secrets.DOCKERHUB_USERNAME }}"
|
RESPONSE=$(curl -s -w "\n%{http_code}" -X PATCH \
|
||||||
|
"https://hub.docker.com/v2/repositories/${DH_USER}/${REPO_PURE}/" \
|
||||||
SHORT_DESC=$(echo -e "${{ env.DESCRIPTION }}" | head -n 1 | cut -c 1-100)
|
-H "Authorization: JWT ${TOKEN}" \
|
||||||
[ -z "$SHORT_DESC" ] && SHORT_DESC="Docker Image for $REPO_PURE"
|
-H "Content-Type: application/json" \
|
||||||
|
-d @payload.json)
|
||||||
echo "📦 Processing README.md (${REPO_PURE})..."
|
|
||||||
|
HTTP_STATUS=$(echo "$RESPONSE" | tail -n 1)
|
||||||
jq -n \
|
BODY=$(echo "$RESPONSE" | head -n -1)
|
||||||
--arg desc "$SHORT_DESC" \
|
|
||||||
--rawfile full_desc README.md \
|
if [ "$HTTP_STATUS" -eq 200 ]; then
|
||||||
'{description: $desc, full_description: $full_desc}' > payload.json
|
echo "✅ README update successfull (HTTP 200)."
|
||||||
|
else
|
||||||
echo "📤 Sending data to Docker Hub API..."
|
echo "❌ Error on update! HTTP Status: $HTTP_STATUS"
|
||||||
RESPONSE=$(curl -s -w "\n%{http_code}" -X PATCH \
|
echo "Answer from Docker Hub: $BODY"
|
||||||
"https://hub.docker.com/v2/repositories/${DH_USER}/${REPO_PURE}/" \
|
exit 1
|
||||||
-H "Authorization: JWT ${TOKEN}" \
|
fi
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d @payload.json)
|
- name: Commit, Tag and Push Changes
|
||||||
|
if: steps.check_changes.outputs.should_build == 'true'
|
||||||
HTTP_STATUS=$(echo "$RESPONSE" | tail -n 1)
|
run: |
|
||||||
BODY=$(echo "$RESPONSE" | head -n -1)
|
git config --local user.email "action@pi-farm.de"
|
||||||
|
git config --local user.name "Gitea Action"
|
||||||
if [ "$HTTP_STATUS" -eq 200 ]; then
|
|
||||||
echo "✅ README update successfull (HTTP 200)."
|
git add VERSION.history README.md docker-compose.yml
|
||||||
else
|
|
||||||
echo "❌ Error on update! HTTP Status: $HTTP_STATUS"
|
git diff --quiet && git diff --staged --quiet || git commit -m "${{ env.FINAL_MSG }} [skip ci]"
|
||||||
echo "Answer from Docker Hub: $BODY"
|
|
||||||
exit 1
|
TARGET_TAG="${{ steps.prep.outputs.docker_tag }}"
|
||||||
fi
|
git tag -f "$TARGET_TAG"
|
||||||
|
|
||||||
- name: Commit, Tag and Push Changes
|
if [[ "${{ gitea.ref }}" == refs/tags/* ]]; then
|
||||||
if: steps.check_changes.outputs.should_build == 'true'
|
echo "🏷️ Build aus Tag getriggert: $TARGET_TAG"
|
||||||
run: |
|
git push -f origin "$TARGET_TAG"
|
||||||
git config --local user.email "action@pi-farm.de"
|
else
|
||||||
git config --local user.name "Gitea Action"
|
echo "🌿 Build aus Branch/Schedule getriggert: ${{ gitea.ref_name }}"
|
||||||
|
git push origin HEAD:${{ gitea.ref_name }}
|
||||||
git add VERSION.history README.md docker-compose.yml
|
git push -f origin "$TARGET_TAG"
|
||||||
|
fi
|
||||||
git diff --quiet && git diff --staged --quiet || git commit -m "${{ env.FINAL_MSG }} [skip ci]"
|
|
||||||
|
|
||||||
TARGET_TAG="${{ steps.prep.outputs.docker_tag }}"
|
|
||||||
git tag -f "$TARGET_TAG"
|
|
||||||
|
|
||||||
if [[ "${{ gitea.ref }}" == refs/tags/* ]]; then
|
|
||||||
echo "🏷️ Build aus Tag getriggert: $TARGET_TAG"
|
|
||||||
git push -f origin "$TARGET_TAG"
|
|
||||||
else
|
|
||||||
echo "🌿 Build aus Branch/Schedule getriggert: ${{ gitea.ref_name }}"
|
|
||||||
git push origin HEAD:${{ gitea.ref_name }}
|
|
||||||
git push -f origin "$TARGET_TAG"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Cleanup Temporary Tags on Docker Hub
|
- name: Cleanup Temporary Tags on Docker Hub
|
||||||
if: steps.check_changes.outputs.should_build == 'true' && contains(steps.prep.outputs.push_targets, 'dockerhub')
|
if: steps.check_changes.outputs.should_build == 'true' && contains(steps.prep.outputs.push_targets, 'dockerhub')
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# base-image-debian-rdp-ldap
|
# base-image-debian-rdp-ldap
|
||||||
Debian Desktop with LDAP-Authentication. To use behind Guacamole with LDAP-Authentication and pass-through to Debian-Desktop.
|
Debian Desktop with LDAP-Authentication and Pulse-Audio. To use behind Guacamole with LDAP-Authentication and pass-through to Debian-Desktop.
|
||||||
|
|
||||||
[](https://git.pi-farm.de/pi-farm/base-image-debian-rdp-ldap/actions)
|
[](https://git.pi-farm.de/pi-farm/base-image-debian-rdp-ldap/actions)
|
||||||
[](__REPO_URL__)
|
[](__REPO_URL__)
|
||||||
@@ -11,18 +11,18 @@ This repository is built and pushed automatically.
|
|||||||
### 🏗️ Platform Support
|
### 🏗️ Platform Support
|
||||||
| Architecture | Status | Base Image | Build Date |
|
| Architecture | Status | Base Image | Build Date |
|
||||||
| :--- | :--- | :--- | :--- |
|
| :--- | :--- | :--- | :--- |
|
||||||
| x86_64 (amd64) | ✅ Active | debian:bookworm | 09.04.2026 15:23 |
|
| x86_64 (amd64) | ✅ Active | debian:trixie | 09.08.2026 07:29 |
|
||||||
| aarch64 (arm64) | ✅ Active | debian:bookworm | 09.04.2026 15:23 |
|
| aarch64 (arm64) | ✅ Active | debian:trixie | 09.08.2026 07:29 |
|
||||||
|
|
||||||
### 🚀 Docker Pull
|
### 🚀 Docker Pull
|
||||||
```bash
|
```bash
|
||||||
docker pull git.pi-farm.de/pi-farm/base-image-debian-rdp-ldap:bookworm-de
|
docker pull git.pi-farm.de/pi-farm/base-image-debian-rdp-ldap:trixie-de
|
||||||
```
|
```
|
||||||
### 🚀 Docker Compose
|
### 🚀 Docker Compose
|
||||||
```yaml
|
```yaml
|
||||||
services:
|
services:
|
||||||
base-image-debian-rdp-ldap:
|
base-image-debian-rdp-ldap:
|
||||||
image: git.pi-farm.de/pi-farm/base-image-debian-rdp-ldap:bookworm-de
|
image: git.pi-farm.de/pi-farm/base-image-debian-rdp-ldap:trixie-de
|
||||||
container_name: base-image-debian-rdp-ldap
|
container_name: base-image-debian-rdp-ldap
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
@@ -50,26 +50,25 @@ docker run -d \
|
|||||||
-e LDAP_SUDO_GROUP=YOUR-SUDO-USERS-GROUP \
|
-e LDAP_SUDO_GROUP=YOUR-SUDO-USERS-GROUP \
|
||||||
-v ./YOUR-PERSISTENT-FOLDER:/home \
|
-v ./YOUR-PERSISTENT-FOLDER:/home \
|
||||||
-p 3889 \
|
-p 3889 \
|
||||||
git.pi-farm.de/pi-farm/base-image-debian-rdp-ldap:bookworm-de
|
git.pi-farm.de/pi-farm/base-image-debian-rdp-ldap:trixie-de
|
||||||
```
|
```
|
||||||
|
|
||||||
*Last updated on: 09.04.2026 15:23*
|
*Last updated on: 09.08.2026 07:29*
|
||||||
|
|
||||||
### 📜 Version History
|
### 📜 Version History
|
||||||
| Version | Date | Status |
|
| Version | Date | Status |
|
||||||
| :--- | :--- | :--- |
|
| :--- | :--- | :--- |
|
||||||
| **bookworm-de** | 09.04.2026 15:23 | ✅ |
|
| **trixie-de** | 09.08.2026 07:29 | ✅ |
|
||||||
| **trixie-de** | 09.04.2026 14:58 | ✅ |
|
| **trixie-de** | 19.07.2026 07:26 | ✅ |
|
||||||
| **bookworm-de** | 09.04.2026 14:13 | ✅ |
|
| **trixie-de** | 28.06.2026 07:27 | ✅ |
|
||||||
| **bookworm-de** | 09.04.2026 13:10 | ✅ |
|
| **trixie-de** | 14.06.2026 07:25 | ✅ |
|
||||||
| **bookworm-de** | 09.04.2026 11:58 | ✅ |
|
| **trixie-de** | 04.06.2026 13:41 | build trixie-de latest ✅ |
|
||||||
| **bookworm-de** | 09.04.2026 10:11 | ✅ |
|
| **trixie-de** | 04.06.2026 12:25 | Trixie build ✅ |
|
||||||
| **bookworm-de** | 07.04.2026 19:27 | ✅ |
|
| **bookworm-de** | 02.06.2026 18:17 | .gitea/workflows/build-and-push.yaml aktualisiert ✅ |
|
||||||
| **bookworm-de** | 07.04.2026 17:38 | ✅ |
|
| **bookworm-de** | 02.06.2026 17:04 | ✅ |
|
||||||
| **bookworm-de** | 05.04.2026 11:47 | ✅ |
|
| **bookworm-de** | 24.05.2026 07:22 | ✅ |
|
||||||
| **bookworm-de** | 05.04.2026 11:20 | ✅ |
|
| **bookworm-de** | 10.05.2026 07:21 | ✅ |
|
||||||
| **bookworm-de** | 04.04.2026 00:31 | ✅ |
|
| **bookworm-de** | 26.04.2026 07:23 | ✅ |
|
||||||
| **bookworm-de** | 02.04.2026 17:26 | ✅ |
|
| **bookworm-de** | 09.04.2026 17:19 | build for bookworm ✅ |
|
||||||
| **bookworm-de** | 02.04.2026 16:44 | ✅ |
|
| **trixie-de** | 09.04.2026 16:44 | build for trixie-de ✅ |
|
||||||
| **bookworm-de** | 02.04.2026 15:37 | ✅ |
|
| **bookworm-de** | 09.04.2026 16:15 | Merge pull request dev (#2) from dev into main Reviewed-on: https://git.pi-farm.de/pi-farm/base-image-debian-rdp-ldap/pulls/2 ✅ |
|
||||||
| **bookworm** | 02.04.2026 14:15 | ✅ |
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
| **trixie-de** | 06.10.2026 17:30 | .gitea/workflows/build-and-push.yaml aktualisiert ✅ |
|
||||||
|
| **trixie-de** | 09.08.2026 07:29 | ✅ |
|
||||||
|
| **trixie-de** | 19.07.2026 07:26 | ✅ |
|
||||||
|
| **trixie-de** | 28.06.2026 07:27 | ✅ |
|
||||||
|
| **trixie-de** | 14.06.2026 07:25 | ✅ |
|
||||||
|
| **trixie-de** | 04.06.2026 13:41 | build trixie-de latest ✅ |
|
||||||
|
| **trixie-de** | 04.06.2026 12:25 | Trixie build ✅ |
|
||||||
|
| **bookworm-de** | 02.06.2026 18:17 | .gitea/workflows/build-and-push.yaml aktualisiert ✅ |
|
||||||
|
| **bookworm-de** | 02.06.2026 17:04 | ✅ |
|
||||||
|
| **bookworm-de** | 24.05.2026 07:22 | ✅ |
|
||||||
|
| **bookworm-de** | 10.05.2026 07:21 | ✅ |
|
||||||
|
| **bookworm-de** | 26.04.2026 07:23 | ✅ |
|
||||||
|
| **bookworm-de** | 09.04.2026 17:19 | build for bookworm ✅ |
|
||||||
|
| **trixie-de** | 09.04.2026 16:44 | build for trixie-de ✅ |
|
||||||
|
| **bookworm-de** | 09.04.2026 16:15 | Merge pull request dev (#2) from dev into main Reviewed-on: https://git.pi-farm.de/pi-farm/base-image-debian-rdp-ldap/pulls/2 ✅ |
|
||||||
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
## BUILD STAGE
|
## BUILD STAGE
|
||||||
BUILD_BASE_IMAGE=debian:bookworm
|
BUILD_BASE_IMAGE=debian:trixie
|
||||||
BUILD_COUNTRY=de
|
BUILD_COUNTRY=de
|
||||||
BUILD_TAG=bookworm-de
|
BUILD_TAG=trixie-de
|
||||||
BUILD_TAG_LATEST=n
|
BUILD_TAG_LATEST=y
|
||||||
BUILD_LANG=de_DE.UTF-8
|
BUILD_LANG=de_DE.UTF-8
|
||||||
BUILD_LANGUAGE=de_DE:de
|
BUILD_LANGUAGE=de_DE:de
|
||||||
BUILD_LC_ALL=de_DE.UTF-8
|
BUILD_LC_ALL=de_DE.UTF-8
|
||||||
|
|||||||
+281
-16
@@ -1,16 +1,281 @@
|
|||||||
services:
|
<!DOCTYPE html>
|
||||||
base-image-debian-rdp-ldap:
|
<html lang="en-US" data-theme="gitea-auto">
|
||||||
image: git.pi-farm.de/pi-farm/base-image-debian-rdp-ldap:bookworm-de
|
<head>
|
||||||
container_name: base-image-debian-rdp-ldap
|
<meta http-equiv="Content-Security-Policy" content="default-src * data: blob:;script-src * 'nonce-2f1114650edc4dcd89ad1b32c2c5a1c0';style-src * 'unsafe-inline';">
|
||||||
restart: unless-stopped
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
ports:
|
<title>Sign In - Gitea: Git with a cup of tea</title>
|
||||||
- 3889
|
<link rel="manifest" href="/assets/site-manifest.json">
|
||||||
environment:
|
<meta name="author" content="Gitea - Git with a cup of tea">
|
||||||
- SSSD_DEBUG_LEVEL=5
|
<meta name="description" content="Gitea (Git with a cup of tea) is a painless self-hosted Git service written in Go">
|
||||||
- LDAP_URI=ldap://YOUR-LDAP-SERVER:389
|
<meta name="keywords" content="go,git,self-hosted,gitea">
|
||||||
- LDAP_BASE_DN=dc=YOUR-DOMAIN,dc=LOC
|
<meta name="referrer" content="same-origin">
|
||||||
- LDAP_BIND_DN=cn=YOUR-BIND-USER,dc=YOUR-DOMAIN,dc=LOC
|
|
||||||
- LDAP_BIND_PASSWORD=YOUR-SUPER-SECRET-BIND-PASSWORD
|
|
||||||
- LDAP_SUDO_GROUP=YOUR-SUDO-USERS-GROUP
|
<link rel="icon" href="/assets/img/favicon.svg" type="image/svg+xml">
|
||||||
volumes:
|
<link rel="alternate icon" href="/assets/img/favicon.png" type="image/png">
|
||||||
- ./YOUR-PERSISTENT-FOLDER:/home
|
|
||||||
|
<meta property="og:title" content="Gitea: Git with a cup of tea">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:image" content="/assets/img/logo.png">
|
||||||
|
<meta property="og:url" content="https://git.pi-farm.de">
|
||||||
|
<meta property="og:description" content="Gitea (Git with a cup of tea) is a painless self-hosted Git service written in Go">
|
||||||
|
|
||||||
|
<meta property="og:site_name" content="Gitea: Git with a cup of tea">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="/assets/css/index.BHUwT9fG.css">
|
||||||
|
<link rel="stylesheet" href="/assets/css/theme-gitea-auto.v3RW7v-i.css">
|
||||||
|
|
||||||
|
|
||||||
|
<script nonce="2f1114650edc4dcd89ad1b32c2c5a1c0">
|
||||||
|
|
||||||
|
window.addEventListener('error', function(e) {window._globalHandlerErrors=window._globalHandlerErrors||[]; window._globalHandlerErrors.push(e);});
|
||||||
|
window.addEventListener('unhandledrejection', function(e) {window._globalHandlerErrors=window._globalHandlerErrors||[]; window._globalHandlerErrors.push(e);});
|
||||||
|
window.config = {
|
||||||
|
appUrl: 'https:\/\/git.pi-farm.de\/',
|
||||||
|
appSubUrl: '',
|
||||||
|
assetUrlPrefix: '\/assets',
|
||||||
|
runModeIsProd: true ,
|
||||||
|
customEmojis: {"codeberg":":codeberg:","git":":git:","gitea":":gitea:","github":":github:","gitlab":":gitlab:","gogs":":gogs:"},
|
||||||
|
pageData: {},
|
||||||
|
notificationSettings: {"EventSourceUpdateTime":10000,"MaxTimeout":60000,"MinTimeout":10000,"TimeoutStep":10000},
|
||||||
|
enableTimeTracking: true ,
|
||||||
|
mermaidMaxSourceCharacters: 50000 ,
|
||||||
|
sharedWorkerUri: '\/assets\/js\/eventsource.sharedworker.DV1Z2uJv.js',
|
||||||
|
|
||||||
|
i18n: {
|
||||||
|
error_occurred: "An error occurred",
|
||||||
|
remove_label_str: "Remove item \"%s\"",
|
||||||
|
modal_confirm: "Confirm",
|
||||||
|
modal_cancel: "Cancel",
|
||||||
|
more_items: "More items",
|
||||||
|
copy_success: "Copied!",
|
||||||
|
copy_error: "Copy failed",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
window.config.pageData = window.config.pageData || {};
|
||||||
|
</script>
|
||||||
|
<script nonce="2f1114650edc4dcd89ad1b32c2c5a1c0" src="/assets/js/iife.D2XhYhS2.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="full height">
|
||||||
|
<noscript>This website requires JavaScript.</noscript>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<nav id="navbar" aria-label="Navigation Bar">
|
||||||
|
<div class="navbar-left">
|
||||||
|
|
||||||
|
<a class="item" id="navbar-logo" href="/" aria-label="Home">
|
||||||
|
<img width="30" height="30" src="/assets/img/logo.svg" alt="Logo" aria-hidden="true">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="ui secondary menu navbar-mobile-right only-mobile">
|
||||||
|
|
||||||
|
|
||||||
|
<button class="item ui icon mini button tw-m-0" id="navbar-expand-toggle" aria-label="Navigation Menu"><svg viewBox="0 0 16 16" class="svg octicon-three-bars" aria-hidden="true" width="16" height="16"><path d="M1 2.75A.75.75 0 0 1 1.75 2h12.5a.75.75 0 0 1 0 1.5H1.75A.75.75 0 0 1 1 2.75m0 5A.75.75 0 0 1 1.75 7h12.5a.75.75 0 0 1 0 1.5H1.75A.75.75 0 0 1 1 7.75M1.75 12h12.5a.75.75 0 0 1 0 1.5H1.75a.75.75 0 0 1 0-1.5"/></svg></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a class="item" href="/explore/repos">Explore</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a class="item" target="_blank" href="https://docs.gitea.com">Help</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="navbar-right">
|
||||||
|
|
||||||
|
|
||||||
|
<a class="item active" rel="nofollow" href="/user/login">
|
||||||
|
<svg viewBox="0 0 16 16" class="svg octicon-sign-in" aria-hidden="true" width="16" height="16"><path d="M2 2.75C2 1.784 2.784 1 3.75 1h2.5a.75.75 0 0 1 0 1.5h-2.5a.25.25 0 0 0-.25.25v10.5c0 .138.112.25.25.25h2.5a.75.75 0 0 1 0 1.5h-2.5A1.75 1.75 0 0 1 2 13.25Zm6.56 4.5h5.69a.75.75 0 0 1 0 1.5H8.56l1.97 1.97a.749.749 0 0 1-.326 1.275.75.75 0 0 1-.734-.215L6.22 8.53a.75.75 0 0 1 0-1.06l3.25-3.25a.749.749 0 0 1 1.275.326.75.75 0 0 1-.215.734Z"/></svg>
|
||||||
|
<span class="tw-ml-1">Sign In</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div role="main" aria-label="Sign In" class="page-content user signin">
|
||||||
|
<div class="ui middle very relaxed page grid">
|
||||||
|
|
||||||
|
<div class="column tw-flex tw-flex-col tw-gap-4 tw-max-w-2xl tw-m-auto">
|
||||||
|
<div class="ui container fluid">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h4 class="ui top attached header center">
|
||||||
|
|
||||||
|
Sign In
|
||||||
|
|
||||||
|
</h4>
|
||||||
|
<div class="ui attached segment">
|
||||||
|
|
||||||
|
<form class="ui form" action="/user/login" method="post">
|
||||||
|
<div class="required field ">
|
||||||
|
<label for="user_name">Username or Email Address</label>
|
||||||
|
<input id="user_name" type="text" name="user_name" value="" autofocus required tabindex="1">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="required field ">
|
||||||
|
<div class="tw-flex tw-mb-1">
|
||||||
|
<label for="password" class="tw-flex-1">Password</label>
|
||||||
|
<a href="/user/forgot_password" tabindex="4">Forgot password?</a>
|
||||||
|
</div>
|
||||||
|
<input id="password" name="password" type="password" value="" autocomplete="current-password" required tabindex="2">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="inline field">
|
||||||
|
<div class="ui checkbox">
|
||||||
|
<label>Remember This Device</label>
|
||||||
|
<input name="remember" type="checkbox" tabindex="5">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<button class="ui primary button tw-w-full" tabindex="3">
|
||||||
|
|
||||||
|
Sign In
|
||||||
|
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="ui container fluid">
|
||||||
|
<div class="ui attached segment header top tw-max-w-2xl tw-m-auto tw-flex tw-flex-col tw-items-center">
|
||||||
|
|
||||||
|
<div id="webauthn-error" class="ui negative message tw-hidden">
|
||||||
|
<div class="header">Could not read your security key.</div>
|
||||||
|
<div id="webauthn-error-msg" class="tw-pt-2"></div>
|
||||||
|
<div class="tw-hidden">
|
||||||
|
<div data-webauthn-error-msg="browser">Your browser does not currently support WebAuthn.</div>
|
||||||
|
<div data-webauthn-error-msg="unknown">An unknown error occurred. Please retry.</div>
|
||||||
|
<div data-webauthn-error-msg="insecure">WebAuthn only supports secure connections. For testing over HTTP, you can use the origin "localhost" or "127.0.0.1".</div>
|
||||||
|
<div data-webauthn-error-msg="unable-to-process">The server could not process your request.</div>
|
||||||
|
<div data-webauthn-error-msg="duplicated">The security key is not permitted for this request. Please make sure that the key is not already registered.</div>
|
||||||
|
<div data-webauthn-error-msg="empty">You must set a name for this key.</div>
|
||||||
|
<div data-webauthn-error-msg="timeout">Timeout reached before your key could be read. Please reload this page and retry.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a class="signin-passkey">Sign in with a passkey</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="page-footer" role="group" aria-label="Footer">
|
||||||
|
<div class="left-links" role="contentinfo" aria-label="About Software">
|
||||||
|
|
||||||
|
<a target="_blank" href="https://about.gitea.com">Powered by Gitea</a>
|
||||||
|
|
||||||
|
|
||||||
|
<span>
|
||||||
|
Version:
|
||||||
|
|
||||||
|
1.27.2
|
||||||
|
|
||||||
|
</span>
|
||||||
|
|
||||||
|
|
||||||
|
<span>
|
||||||
|
Page: <strong>2ms</strong>
|
||||||
|
Template: <strong>0ms</strong>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="right-links" role="group" aria-label="Links">
|
||||||
|
<div class="ui dropdown custom" id="footer-theme-selector">
|
||||||
|
<span class="default-text"><div class="theme-menu-item" data-tooltip-content=""><svg viewBox="490 490 820 820" class="svg gitea-eclipse" aria-hidden="true" width="16" height="16"><path d="M866.7 582.1A321.3 321.3 0 0 0 738.6 623a317.3 317.3 0 0 0-109.1 108.5A418 418 0 0 0 609 772a335.3 335.3 0 0 0-19.6 71.5 205.2 205.2 0 0 0-2.8 45c0 25.8.2 29.3 2.8 45 4.1 25.4 9.9 46.4 19.6 71.5a314.2 314.2 0 0 0 111.6 137.3A306.8 306.8 0 0 0 893 1196a308.6 308.6 0 0 0 303.6-262.5c2.6-15.7 2.8-19.2 2.8-45s-.2-29.3-2.8-45A335.3 335.3 0 0 0 1177 772a314.2 314.2 0 0 0-111.6-137.3A308.3 308.3 0 0 0 918 582c-13-1.1-38.2-1.1-51.3.1M747 663.5l-2.4 16.7c-4 26.4-4.9 41.1-4.3 65.3a323.7 323.7 0 0 0 37.2 145c18.2 36 41.3 66.6 72 95.5a346.4 346.4 0 0 0 208.5 93.1l18 1.6 4.5.5-8.5 8a259.3 259.3 0 0 1-141.5 65.8 281 281 0 0 1-123.9-11.4 267.2 267.2 0 0 1-181.7-269.9c2-27.6 5.7-47.6 13.3-70.7a281.2 281.2 0 0 1 46.4-85c8-10.1 28-30.2 37.9-38.1 13.8-11.1 24.5-18.3 24.5-16.4"/></svg> Auto </div></span>
|
||||||
|
<div class="menu theme-menu"></div>
|
||||||
|
</div>
|
||||||
|
<div class="ui dropdown upward">
|
||||||
|
<span class="flex-text-inline"><svg viewBox="0 0 16 16" class="svg octicon-globe" aria-hidden="true" width="14" height="14"><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0M5.78 8.75a9.64 9.64 0 0 0 1.363 4.177q.383.64.857 1.215c.245-.296.551-.705.857-1.215A9.64 9.64 0 0 0 10.22 8.75Zm4.44-1.5a9.64 9.64 0 0 0-1.363-4.177c-.307-.51-.612-.919-.857-1.215a10 10 0 0 0-.857 1.215A9.64 9.64 0 0 0 5.78 7.25Zm-5.944 1.5H1.543a6.51 6.51 0 0 0 4.666 5.5q-.184-.271-.352-.552c-.715-1.192-1.437-2.874-1.581-4.948m-2.733-1.5h2.733c.144-2.074.866-3.756 1.58-4.948q.18-.295.353-.552a6.51 6.51 0 0 0-4.666 5.5m10.181 1.5c-.144 2.074-.866 3.756-1.58 4.948q-.18.296-.353.552a6.51 6.51 0 0 0 4.666-5.5Zm2.733-1.5a6.51 6.51 0 0 0-4.666-5.5q.184.272.353.552c.714 1.192 1.436 2.874 1.58 4.948Z"/></svg> English</span>
|
||||||
|
<div class="menu language-menu">
|
||||||
|
<a lang="id-ID" data-url="/?lang=id-ID" class="item ">Bahasa Indonesia</a>
|
||||||
|
<a lang="de-DE" data-url="/?lang=de-DE" class="item ">Deutsch</a>
|
||||||
|
<a lang="en-US" data-url="/?lang=en-US" class="item selected">English</a>
|
||||||
|
<a lang="es-ES" data-url="/?lang=es-ES" class="item ">Español</a>
|
||||||
|
<a lang="fr-FR" data-url="/?lang=fr-FR" class="item ">Français</a>
|
||||||
|
<a lang="ga-IE" data-url="/?lang=ga-IE" class="item ">Gaeilge</a>
|
||||||
|
<a lang="it-IT" data-url="/?lang=it-IT" class="item ">Italiano</a>
|
||||||
|
<a lang="lv-LV" data-url="/?lang=lv-LV" class="item ">Latviešu</a>
|
||||||
|
<a lang="hu-HU" data-url="/?lang=hu-HU" class="item ">Magyar nyelv</a>
|
||||||
|
<a lang="nl-NL" data-url="/?lang=nl-NL" class="item ">Nederlands</a>
|
||||||
|
<a lang="pl-PL" data-url="/?lang=pl-PL" class="item ">Polski</a>
|
||||||
|
<a lang="pt-PT" data-url="/?lang=pt-PT" class="item ">Português de Portugal</a>
|
||||||
|
<a lang="pt-BR" data-url="/?lang=pt-BR" class="item ">Português do Brasil</a>
|
||||||
|
<a lang="fi-FI" data-url="/?lang=fi-FI" class="item ">Suomi</a>
|
||||||
|
<a lang="sv-SE" data-url="/?lang=sv-SE" class="item ">Svenska</a>
|
||||||
|
<a lang="tr-TR" data-url="/?lang=tr-TR" class="item ">Türkçe</a>
|
||||||
|
<a lang="cs-CZ" data-url="/?lang=cs-CZ" class="item ">Čeština</a>
|
||||||
|
<a lang="el-GR" data-url="/?lang=el-GR" class="item ">Ελληνικά</a>
|
||||||
|
<a lang="bg-BG" data-url="/?lang=bg-BG" class="item ">Български</a>
|
||||||
|
<a lang="ru-RU" data-url="/?lang=ru-RU" class="item ">Русский</a>
|
||||||
|
<a lang="uk-UA" data-url="/?lang=uk-UA" class="item ">Українська</a>
|
||||||
|
<a lang="fa-IR" data-url="/?lang=fa-IR" class="item ">فارسی</a>
|
||||||
|
<a lang="ml-IN" data-url="/?lang=ml-IN" class="item ">മലയാളം</a>
|
||||||
|
<a lang="ja-JP" data-url="/?lang=ja-JP" class="item ">日本語</a>
|
||||||
|
<a lang="zh-CN" data-url="/?lang=zh-CN" class="item ">简体中文</a>
|
||||||
|
<a lang="zh-TW" data-url="/?lang=zh-TW" class="item ">繁體中文(台灣)</a>
|
||||||
|
<a lang="zh-HK" data-url="/?lang=zh-HK" class="item ">繁體中文(香港)</a>
|
||||||
|
<a lang="ko-KR" data-url="/?lang=ko-KR" class="item ">한국어</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a href="/assets/licenses.txt">Licenses</a>
|
||||||
|
<a href="/api/swagger">API</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<script nonce="2f1114650edc4dcd89ad1b32c2c5a1c0" type="module" src="/assets/js/index.8BwIzI4A.js"></script>
|
||||||
|
|
||||||
|
<script nonce="2f1114650edc4dcd89ad1b32c2c5a1c0" type="module">
|
||||||
|
if (!window.config?.frontendInited && window.config?.runModeIsProd) alert("Frontend is not initialized, check console errors or asset files.");
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
Reference in new issue
Block a user