From be3bf30724687a799730097b0fc66491cee1ada2 Mon Sep 17 00:00:00 2001 From: DragonSlayer_14 Date: Mon, 21 Sep 2026 00:27:08 +0200 Subject: [PATCH] CI: Fuegt automatisiertes Nightly-Release hinzu und behebt Zeitzone bei geplanten Workflows - Neuer Workflow "nightly-pr.yaml": Erstellt und merged taeglich automatisch einen Pull Request von dev nach nightly (09:00 Uhr Europe/Berlin); legt den nightly-Branch bei Bedarf initial von dev an. - Neuer Workflow "nightly.yaml": Baut und veroeffentlicht Pakete bei Aenderungen auf nightly in den nightly-Kanal der Paket-Registry (Debian/RPM/Arch); erstellt bewusst kein Gitea-Release (auch kein Nightly-Docker-Image, analog zum Umfang der urspruenglichen Anfrage). - CRON_TZ=Europe/Berlin in security-scan.yaml und trufflehog-scan.yaml ergaenzt: Gitea Actions interpretiert schedule-Cron sonst in der lokalen Zeitzone des Gitea-Servers statt in der beabsichtigten Zeitzone. Co-Authored-By: Claude Sonnet 5 --- .gitea/workflows/nightly-pr.yaml | 91 ++++++++++++++ .gitea/workflows/nightly.yaml | 171 ++++++++++++++++++++++++++ .gitea/workflows/security-scan.yaml | 2 +- .gitea/workflows/trufflehog-scan.yaml | 2 +- 4 files changed, 264 insertions(+), 2 deletions(-) create mode 100644 .gitea/workflows/nightly-pr.yaml create mode 100644 .gitea/workflows/nightly.yaml diff --git a/.gitea/workflows/nightly-pr.yaml b/.gitea/workflows/nightly-pr.yaml new file mode 100644 index 0000000..287b251 --- /dev/null +++ b/.gitea/workflows/nightly-pr.yaml @@ -0,0 +1,91 @@ +name: Nightly Auto-Merge (Dev → Nightly) + +on: + schedule: + # Gitea Actions interpretiert 'schedule'-Cron standardmaessig in der lokalen + # Zeitzone des Gitea-Servers (anders als GitHub Actions, das immer UTC nutzt). + # Das CRON_TZ-Praefix ist eine Gitea-Erweiterung und legt die Zeitzone explizit + # und DST-sicher fest, unabhaengig von der Server-Konfiguration. + - cron: "CRON_TZ=Europe/Berlin 0 9 * * *" + workflow_dispatch: + +jobs: + merge-dev-into-nightly: + name: Erstelle & merge automatisch PR von dev nach nightly + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v7 + with: + fetch-depth: 0 + token: ${{ secrets.PACKAGE_TOKEN || secrets.RELEASE_TOKEN || secrets.PUBLISH_TOKEN || secrets.API_TOKEN || secrets.PAT_TOKEN || secrets.CUSTOM_TOKEN || secrets.GITEA_TOKEN || secrets.GITHUB_TOKEN || github.token }} + + - name: Stelle sicher, dass der nightly-Branch existiert + run: | + git fetch origin dev + if git ls-remote --exit-code --heads origin nightly > /dev/null 2>&1; then + echo "nightly-Branch existiert bereits." + else + echo "nightly-Branch existiert noch nicht, erstelle ihn initial von dev..." + git push origin origin/dev:refs/heads/nightly + fi + + - name: Prüfe auf Unterschiede zwischen dev und nightly + id: diff + run: | + git fetch origin nightly + if git diff --quiet origin/nightly origin/dev; then + echo "Keine Unterschiede zwischen dev und nightly, überspringe." + echo "has_changes=false" >> "$GITHUB_OUTPUT" + else + echo "has_changes=true" >> "$GITHUB_OUTPUT" + fi + + - name: Prüfe auf bereits offenen PR nach nightly + id: check_pr + if: steps.diff.outputs.has_changes == 'true' + env: + GITEA_URL: ${{ gitea.server_url || github.server_url }} + REPO: ${{ gitea.repository || github.repository }} + TOKEN: ${{ secrets.PACKAGE_TOKEN || secrets.RELEASE_TOKEN || secrets.PUBLISH_TOKEN || secrets.API_TOKEN || secrets.PAT_TOKEN || secrets.CUSTOM_TOKEN || secrets.GITEA_TOKEN || secrets.GITHUB_TOKEN || github.token }} + run: | + OPEN_PRS=$(curl -s -H "Authorization: token ${TOKEN}" "${GITEA_URL}/api/v1/repos/${REPO}/pulls?state=open&limit=50") + PR_NUMBER=$(echo "$OPEN_PRS" | jq -r '[.[] | select(.base.ref == "nightly" and .head.ref == "dev")][0].number // empty') + echo "Bereits offener dev→nightly PR: ${PR_NUMBER:-keiner}" + echo "pr_number=${PR_NUMBER}" >> "$GITHUB_OUTPUT" + + - name: Erstelle PR (dev -> nightly) + id: create_pr + if: steps.diff.outputs.has_changes == 'true' && steps.check_pr.outputs.pr_number == '' + env: + GITEA_URL: ${{ gitea.server_url || github.server_url }} + REPO: ${{ gitea.repository || github.repository }} + TOKEN: ${{ secrets.PACKAGE_TOKEN || secrets.RELEASE_TOKEN || secrets.PUBLISH_TOKEN || secrets.API_TOKEN || secrets.PAT_TOKEN || secrets.CUSTOM_TOKEN || secrets.GITEA_TOKEN || secrets.GITHUB_TOKEN || github.token }} + run: | + DATE="$(date -u +%Y-%m-%d)" + PAYLOAD=$(jq -n --arg title "Nightly-Build: Merge dev in nightly (${DATE})" --arg head "dev" --arg base "nightly" \ + '{title: $title, head: $head, base: $base}') + RESP=$(curl -f -s -S -X POST \ + -H "Authorization: token ${TOKEN}" \ + -H "Content-Type: application/json" \ + -d "$PAYLOAD" \ + "${GITEA_URL}/api/v1/repos/${REPO}/pulls") + PR_NUMBER=$(echo "$RESP" | jq -r '.number') + echo "PR #${PR_NUMBER} erstellt." + echo "pr_number=${PR_NUMBER}" >> "$GITHUB_OUTPUT" + + - name: Merge PR automatisch + if: steps.diff.outputs.has_changes == 'true' + env: + GITEA_URL: ${{ gitea.server_url || github.server_url }} + REPO: ${{ gitea.repository || github.repository }} + TOKEN: ${{ secrets.PACKAGE_TOKEN || secrets.RELEASE_TOKEN || secrets.PUBLISH_TOKEN || secrets.API_TOKEN || secrets.PAT_TOKEN || secrets.CUSTOM_TOKEN || secrets.GITEA_TOKEN || secrets.GITHUB_TOKEN || github.token }} + PR_NUMBER: ${{ steps.create_pr.outputs.pr_number || steps.check_pr.outputs.pr_number }} + run: | + echo "Merge PR #${PR_NUMBER} automatisch (dev -> nightly)..." + curl -f -s -S -X POST \ + -H "Authorization: token ${TOKEN}" \ + -H "Content-Type: application/json" \ + -d '{"Do": "merge"}' \ + "${GITEA_URL}/api/v1/repos/${REPO}/pulls/${PR_NUMBER}/merge" + echo "PR #${PR_NUMBER} erfolgreich gemerged." diff --git a/.gitea/workflows/nightly.yaml b/.gitea/workflows/nightly.yaml new file mode 100644 index 0000000..8f991e9 --- /dev/null +++ b/.gitea/workflows/nightly.yaml @@ -0,0 +1,171 @@ +name: Nightly Build & Publish + +on: + push: + branches: + - nightly + +jobs: + detect-changes: + name: Erkenne relevante Code-Änderungen + runs-on: ubuntu-latest + outputs: + code_changed: ${{ steps.filter.outputs.code }} + steps: + - name: Checkout Repository + uses: actions/checkout@v7 + + - name: Prüfe auf Änderungen am Programmcode + uses: dorny/paths-filter@v4 + id: filter + with: + filters: | + code: + - 'src/**' + - 'Cargo.toml' + - 'Cargo.lock' + - 'scripts/**' + - '.cargo/**' + - '.gitea/workflows/nightly.yaml' + + build-and-publish: + name: Build & Publish Packages (Nightly) + needs: detect-changes + if: needs.detect-changes.outputs.code_changed == 'true' + runs-on: ubuntu-latest + env: + CARGO_BINSTALL_VERSION: "1.23.0" + CARGO_DEB_VERSION: "3.8.0" + CARGO_GENERATE_RPM_VERSION: "0.21.0" + steps: + - name: Checkout Repository + uses: actions/checkout@v7 + + - name: Install Rust Toolchain + uses: actions-rust-lang/setup-rust-toolchain@v2 + with: + toolchain: stable + cache: false + + - name: Cache Cargo-Abhängigkeiten & Build-Artefakte + uses: Swatinem/rust-cache@v2 + + - name: Alte Paketierungs-Ausgaben aus dem Cache entfernen + run: rm -rf target/debian target/generate-rpm target/arch + + - name: Install Cross-Compilation Toolchains (apt) + run: | + sudo apt-get update + sudo apt-get install -y gcc-aarch64-linux-gnu gcc-i686-linux-gnu + + - name: Ermittle Rust-Version für Rustup-Target-Cache-Key + run: echo "RUST_VERSION=$(rustc --version | awk '{print $2}')" >> "$GITHUB_ENV" + + - name: Cache Rustup Cross-Compilation-Targets + id: cache-rustup-targets + uses: actions/cache@v6 + with: + path: | + ~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu + ~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-unknown-linux-gnu + key: rustup-targets-${{ runner.os }}-${{ env.RUST_VERSION }} + + - name: Add Rust Cross-Compilation Targets + if: steps.cache-rustup-targets.outputs.cache-hit != 'true' + run: rustup target add aarch64-unknown-linux-gnu i686-unknown-linux-gnu + + - name: PATH um Cargo-bin-Verzeichnis ergänzen + run: | + mkdir -p ~/.cargo/bin + echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" + + - name: Cache Packaging-Tools (cargo-binstall, cargo-deb, cargo-generate-rpm) + id: cache-packaging-tools + uses: actions/cache@v6 + with: + path: | + ~/.cargo/bin/cargo-binstall + ~/.cargo/bin/cargo-deb + ~/.cargo/bin/cargo-generate-rpm + key: packaging-tools-${{ runner.os }}-${{ env.CARGO_BINSTALL_VERSION }}-${{ env.CARGO_DEB_VERSION }}-${{ env.CARGO_GENERATE_RPM_VERSION }} + + - name: Install Packaging Tools (Prebuilt Binaries) + if: steps.cache-packaging-tools.outputs.cache-hit != 'true' + run: | + curl -fsSL "https://github.com/cargo-bins/cargo-binstall/releases/download/v${CARGO_BINSTALL_VERSION}/cargo-binstall-x86_64-unknown-linux-musl.tgz" | tar -xz -C ~/.cargo/bin + ~/.cargo/bin/cargo-binstall -y --no-symlinks "cargo-deb@${CARGO_DEB_VERSION}" "cargo-generate-rpm@${CARGO_GENERATE_RPM_VERSION}" + + - name: Run Tests + run: | + cargo test + + - name: Build Release Binaries + run: | + cargo build --release --target x86_64-unknown-linux-gnu + cargo build --release --target aarch64-unknown-linux-gnu + cargo build --release --target i686-unknown-linux-gnu + + - name: Determine Build Number + id: build_num + env: + GITEA_URL: ${{ gitea.server_url || github.server_url }} + REPO: ${{ gitea.repository || github.repository }} + REPO_OWNER: ${{ gitea.repository_owner || github.repository_owner }} + TOKEN: ${{ secrets.PACKAGE_TOKEN || secrets.RELEASE_TOKEN || secrets.PUBLISH_TOKEN || secrets.API_TOKEN || secrets.PAT_TOKEN || secrets.CUSTOM_TOKEN || secrets.GITEA_TOKEN || secrets.GITHUB_TOKEN || github.token }} + run: | + BUILD_NUM=$(python3 scripts/get-build-number.py) + echo "build_number=${BUILD_NUM}" >> $GITHUB_OUTPUT + echo "BUILD_NUMBER=${BUILD_NUM}" >> $GITHUB_ENV + echo "Ermittelte Build-Nummer: ${BUILD_NUM}" + + - name: Build Debian Packages (.deb) + run: | + cargo deb --target x86_64-unknown-linux-gnu --deb-revision "${BUILD_NUMBER}" --no-build + cargo deb --target aarch64-unknown-linux-gnu --deb-revision "${BUILD_NUMBER}" --no-build + cargo deb --target i686-unknown-linux-gnu --deb-revision "${BUILD_NUMBER}" --no-build + + - name: Build Fedora / RPM Packages (.rpm) + run: | + mkdir -p target/generate-rpm + cargo generate-rpm --target x86_64-unknown-linux-gnu -s "release=\"${BUILD_NUMBER}\"" -o target/generate-rpm + cargo generate-rpm --target aarch64-unknown-linux-gnu -s "release=\"${BUILD_NUMBER}\"" -o target/generate-rpm + cargo generate-rpm --target i686-unknown-linux-gnu -s "release=\"${BUILD_NUMBER}\"" -o target/generate-rpm + + - name: Build Arch Linux Packages (.pkg.tar.zst) + run: | + python3 scripts/package-arch.py --target x86_64-unknown-linux-gnu --pkgrel "${BUILD_NUMBER}" + python3 scripts/package-arch.py --target aarch64-unknown-linux-gnu --pkgrel "${BUILD_NUMBER}" + python3 scripts/package-arch.py --target i686-unknown-linux-gnu --pkgrel "${BUILD_NUMBER}" + + - name: Publish Packages to Gitea Package Registry + env: + GITEA_URL: ${{ gitea.server_url || github.server_url }} + REPO_OWNER: ${{ gitea.repository_owner || github.repository_owner }} + TOKEN: ${{ secrets.PACKAGE_TOKEN || secrets.RELEASE_TOKEN || secrets.PUBLISH_TOKEN || secrets.API_TOKEN || secrets.PAT_TOKEN || secrets.CUSTOM_TOKEN || secrets.GITEA_TOKEN || secrets.GITHUB_TOKEN || github.token }} + run: | + echo "Veröffentliche Debian-Paket (Distribution: nightly, Component: main)..." + for deb in target/debian/*.deb; do + [ -f "$deb" ] || continue + curl -f -s -S -X PUT \ + -H "Authorization: token ${TOKEN}" \ + --upload-file "$deb" \ + "${GITEA_URL}/api/packages/${REPO_OWNER}/debian/pool/nightly/main/upload" + done + + echo "Veröffentliche Fedora/RPM-Paket (Gruppe: nightly)..." + for rpm in target/generate-rpm/*.rpm; do + [ -f "$rpm" ] || continue + curl -f -s -S -X PUT \ + -H "Authorization: token ${TOKEN}" \ + --upload-file "$rpm" \ + "${GITEA_URL}/api/packages/${REPO_OWNER}/rpm/nightly/upload" + done + + echo "Veröffentliche Arch Linux-Paket (Repository: nightly)..." + for pkg in target/arch/*.pkg.tar.zst; do + [ -f "$pkg" ] || continue + curl -f -s -S -X PUT \ + -H "Authorization: token ${TOKEN}" \ + --upload-file "$pkg" \ + "${GITEA_URL}/api/packages/${REPO_OWNER}/arch/nightly" + done diff --git a/.gitea/workflows/security-scan.yaml b/.gitea/workflows/security-scan.yaml index 040bef7..54d3bea 100644 --- a/.gitea/workflows/security-scan.yaml +++ b/.gitea/workflows/security-scan.yaml @@ -8,7 +8,7 @@ on: - dev pull_request: schedule: - - cron: "0 5 * * 1" + - cron: "CRON_TZ=Europe/Berlin 0 5 * * 1" workflow_dispatch: jobs: diff --git a/.gitea/workflows/trufflehog-scan.yaml b/.gitea/workflows/trufflehog-scan.yaml index c6457cd..b059507 100644 --- a/.gitea/workflows/trufflehog-scan.yaml +++ b/.gitea/workflows/trufflehog-scan.yaml @@ -4,7 +4,7 @@ on: push: pull_request: schedule: - - cron: "0 6 * * 1" + - cron: "CRON_TZ=Europe/Berlin 0 6 * * 1" workflow_dispatch: jobs: