diff --git a/.forgejo/workflows/auto-update-build.yaml b/.forgejo/workflows/auto-update-build.yaml new file mode 100644 index 0000000..1f77096 --- /dev/null +++ b/.forgejo/workflows/auto-update-build.yaml @@ -0,0 +1,113 @@ +name: Auto Update Build + +on: + pull_request: + types: [opened, synchronize] + branches: + - master + +jobs: + build: + # Only run for auto-update branches + if: startsWith(github.head_ref, 'auto-update/') + runs-on: nix + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Extract LXC hosts + id: hosts + run: | + set -euo pipefail + HOSTS=$(nix eval --json .#colmena --apply 'x: builtins.filter (n: n != "meta" && builtins.elem "lxc" (x.${n}.deployment.tags or [])) (builtins.attrNames x)') + + # Validate the output is a non-empty JSON array + if ! echo "$HOSTS" | jq -e '. | if type == "array" and length > 0 then true else false end' > /dev/null 2>&1; then + echo "Error: No LXC hosts found or invalid JSON output: $HOSTS" + exit 1 + fi + + echo "$HOSTS" > hosts.json + echo "Discovered hosts: $HOSTS" + + - name: Build all hosts + id: build + run: | + set -euo pipefail + + if [ ! -f hosts.json ]; then + echo "Error: hosts.json not found" + exit 1 + fi + + HOSTS=$(cat hosts.json) + echo "Building hosts: $HOSTS" + + FAILED_HOSTS="" + SUCCESS_HOSTS="" + + declare -A BUILD_TIMES + + for HOST in $(echo "$HOSTS" | jq -r '.[]'); do + echo "" + echo "==========================================" + echo "Building: $HOST" + echo "==========================================" + + START_TIME=$(date +%s) + + if nix build ".#nixosConfigurations.${HOST}.config.system.build.toplevel" --no-link --quiet 2>&1 | tee "build-${HOST}.txt"; then + END_TIME=$(date +%s) + DURATION=$((END_TIME - START_TIME)) + DURATION_FMT=$(printf '%dm %ds' $((DURATION/60)) $((DURATION%60))) + BUILD_TIMES[$HOST]="$DURATION_FMT" + echo "✓ Build succeeded: $HOST (${DURATION_FMT})" + SUCCESS_HOSTS="$SUCCESS_HOSTS $HOST" + else + END_TIME=$(date +%s) + DURATION=$((END_TIME - START_TIME)) + DURATION_FMT=$(printf '%dm %ds' $((DURATION/60)) $((DURATION%60))) + BUILD_TIMES[$HOST]="$DURATION_FMT" + echo "✗ Build failed: $HOST (${DURATION_FMT})" + FAILED_HOSTS="$FAILED_HOSTS $HOST" + fi + done + + echo "" + echo "==========================================" + echo "Build Summary" + echo "==========================================" + echo "Succeeded:$SUCCESS_HOSTS" + echo "Failed:$FAILED_HOSTS" + echo "" + echo "Build times:" + for HOST in "${!BUILD_TIMES[@]}"; do + echo " $HOST: ${BUILD_TIMES[$HOST]}" + done + + if [ -n "$FAILED_HOSTS" ]; then + echo "Some builds failed" + exit 1 + fi + continue-on-error: true + + - name: Upload build logs + if: always() + uses: forgejo/upload-artifact@v4 + with: + name: build-logs + path: build-*.txt + retention-days: 7 + + - name: Check build result + run: | + if [ "${{ steps.build.outcome }}" == "failure" ]; then + echo "Some builds failed - check build-logs artifact" + exit 1 + fi + + - name: Cleanup + if: always() + run: | + nix-collect-garbage -d + rm -rf result .direnv diff --git a/.forgejo/workflows/auto-update-pr.yaml b/.forgejo/workflows/auto-update-pr.yaml new file mode 100644 index 0000000..0add79b --- /dev/null +++ b/.forgejo/workflows/auto-update-pr.yaml @@ -0,0 +1,65 @@ +name: Weekly Flake Update PR + +on: + schedule: + # Every Friday at 22:00 UTC + - cron: '0 22 * * 5' + workflow_dispatch: {} + +jobs: + create-pr: + runs-on: nix + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Configure Git + run: | + git config user.name "Flake Update Bot" + git config user.email "git@noreply.local" + + - name: Update flake inputs + run: nix flake update + + - name: Check for changes + id: changes + run: | + if git diff --quiet flake.lock; then + echo "changed=false" >> $FORGEJO_OUTPUT + echo "No changes to flake.lock" + else + echo "changed=true" >> $FORGEJO_OUTPUT + echo "flake.lock has been updated" + fi + + - name: Create branch and commit + id: commit + if: steps.changes.outputs.changed == 'true' + run: | + BRANCH_NAME="auto-update/$(date +%Y-%m-%d)" + git checkout -b "$BRANCH_NAME" + git add flake.lock + git commit -m "chore: update flake inputs $(date +%Y-%m-%d)" + git push origin "$BRANCH_NAME" + echo "branch_name=$BRANCH_NAME" >> $FORGEJO_OUTPUT + echo "Created and pushed branch: $BRANCH_NAME" + + - name: Create Pull Request + if: steps.changes.outputs.changed == 'true' + env: + FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }} + run: | + DATE=$(date +%Y-%m-%d) + + curl -X POST \ + -H "Authorization: token $FORGEJO_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "title": "chore: weekly flake update '"$DATE"'", + "body": "Automated flake update from CI.\n\nThis PR updates all flake inputs.\n\n**Note:** Build verification will run automatically on this PR.\n\nGenerated on: '"$(date -Iseconds)"'", + "head": "'"${{ steps.commit.outputs.branch_name }}"'", + "base": "master" + }' \ + "${{ forgejo.api_url }}/repos/${{ forgejo.repository }}/pulls"