From 9e427acf83fa11b3744326178c8d07098780c48a Mon Sep 17 00:00:00 2001 From: zack Date: Sat, 19 Oct 2024 23:25:25 -0400 Subject: [PATCH] unmodularize because i can't be bothered --- .github/actions/create-hydra-jobset.yml | 79 ------ .../actions/create-hydra-jobset/action.yml | 79 ------ .github/actions/trigger-hydra-build.yml | 40 --- .github/actions/wait-for-hydra-build.yml | 91 ------- .github/workflows/update.yml | 242 +++++++++++++++--- 5 files changed, 203 insertions(+), 328 deletions(-) delete mode 100644 .github/actions/create-hydra-jobset.yml delete mode 100644 .github/actions/create-hydra-jobset/action.yml delete mode 100644 .github/actions/trigger-hydra-build.yml delete mode 100644 .github/actions/wait-for-hydra-build.yml diff --git a/.github/actions/create-hydra-jobset.yml b/.github/actions/create-hydra-jobset.yml deleted file mode 100644 index e149077..0000000 --- a/.github/actions/create-hydra-jobset.yml +++ /dev/null @@ -1,79 +0,0 @@ -name: 'Create Hydra Jobset' -description: 'Creates or updates a jobset on a Hydra CI server' -inputs: - hydra_instance: - description: 'URL of the Hydra instance' - required: true - hydra_project: - description: 'Name of the Hydra project' - required: true - hydra_jobset: - description: 'Name of the Hydra jobset' - required: true - hydra_username: - description: 'Username for Hydra authentication' - required: true - hydra_password: - description: 'Password for Hydra authentication' - required: true - flake_uri: - description: 'URI of the flake to build' - required: true - description: - description: 'Description of the jobset' - required: false - default: 'Auto-created jobset' - enabled: - description: 'Whether the jobset should be enabled' - required: false - default: '1' - visible: - description: 'Whether the jobset should be visible' - required: false - default: '0' - keepnr: - description: 'Number of builds to keep' - required: false - default: '3' - checkinterval: - description: 'Interval between checks in seconds' - required: false - default: '300' - -runs: - using: "composite" - steps: - - name: Create or update Hydra jobset - shell: bash - run: | - AUTH_HEADER="Authorization: Basic $(echo -n '${{ inputs.hydra_username }}:${{ inputs.hydra_password }}' | base64)" - - # Prepare the JSON payload - payload=$(cat << EOF - { - "enabled": ${{ inputs.enabled }}, - "visible": ${{ inputs.visible }}, - "keepnr": ${{ inputs.keepnr }}, - "checkinterval": ${{ inputs.checkinterval }}, - "description": "${{ inputs.description }}", - "flake": "${{ inputs.flake_uri }}", - "type": 1 - } - EOF - ) - - # Send the request to create or update the jobset - response=$(curl -s -X PUT \ - -H "Content-Type: application/json" \ - -H "$AUTH_HEADER" \ - -d "$payload" \ - "${{ inputs.hydra_instance }}/jobset/${{ inputs.hydra_project }}/${{ inputs.hydra_jobset }}") - - # Check the response - if [[ $response == *"\"jobset\":\"${{ inputs.hydra_jobset }}\""* ]]; then - echo "Hydra jobset created or updated successfully" - else - echo "Failed to create or update Hydra jobset" - echo "Response: $response" - exit 1 - fi diff --git a/.github/actions/create-hydra-jobset/action.yml b/.github/actions/create-hydra-jobset/action.yml deleted file mode 100644 index e149077..0000000 --- a/.github/actions/create-hydra-jobset/action.yml +++ /dev/null @@ -1,79 +0,0 @@ -name: 'Create Hydra Jobset' -description: 'Creates or updates a jobset on a Hydra CI server' -inputs: - hydra_instance: - description: 'URL of the Hydra instance' - required: true - hydra_project: - description: 'Name of the Hydra project' - required: true - hydra_jobset: - description: 'Name of the Hydra jobset' - required: true - hydra_username: - description: 'Username for Hydra authentication' - required: true - hydra_password: - description: 'Password for Hydra authentication' - required: true - flake_uri: - description: 'URI of the flake to build' - required: true - description: - description: 'Description of the jobset' - required: false - default: 'Auto-created jobset' - enabled: - description: 'Whether the jobset should be enabled' - required: false - default: '1' - visible: - description: 'Whether the jobset should be visible' - required: false - default: '0' - keepnr: - description: 'Number of builds to keep' - required: false - default: '3' - checkinterval: - description: 'Interval between checks in seconds' - required: false - default: '300' - -runs: - using: "composite" - steps: - - name: Create or update Hydra jobset - shell: bash - run: | - AUTH_HEADER="Authorization: Basic $(echo -n '${{ inputs.hydra_username }}:${{ inputs.hydra_password }}' | base64)" - - # Prepare the JSON payload - payload=$(cat << EOF - { - "enabled": ${{ inputs.enabled }}, - "visible": ${{ inputs.visible }}, - "keepnr": ${{ inputs.keepnr }}, - "checkinterval": ${{ inputs.checkinterval }}, - "description": "${{ inputs.description }}", - "flake": "${{ inputs.flake_uri }}", - "type": 1 - } - EOF - ) - - # Send the request to create or update the jobset - response=$(curl -s -X PUT \ - -H "Content-Type: application/json" \ - -H "$AUTH_HEADER" \ - -d "$payload" \ - "${{ inputs.hydra_instance }}/jobset/${{ inputs.hydra_project }}/${{ inputs.hydra_jobset }}") - - # Check the response - if [[ $response == *"\"jobset\":\"${{ inputs.hydra_jobset }}\""* ]]; then - echo "Hydra jobset created or updated successfully" - else - echo "Failed to create or update Hydra jobset" - echo "Response: $response" - exit 1 - fi diff --git a/.github/actions/trigger-hydra-build.yml b/.github/actions/trigger-hydra-build.yml deleted file mode 100644 index 0e800c0..0000000 --- a/.github/actions/trigger-hydra-build.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: 'Trigger Hydra Build' -description: 'Triggers a build on a Hydra CI server' -inputs: - hydra_instance: - description: 'URL of the Hydra instance' - required: true - hydra_project: - description: 'Name of the Hydra project' - required: true - hydra_jobset: - description: 'Name of the Hydra jobset' - required: true - hydra_username: - description: 'Username for Hydra authentication' - required: true - hydra_password: - description: 'Password for Hydra authentication' - required: true - -runs: - using: "composite" - steps: - - name: Trigger Hydra build - shell: bash - run: | - AUTH_HEADER="Authorization: Basic $(echo -n '${{ inputs.hydra_username }}:${{ inputs.hydra_password }}' | base64)" - response=$(curl -s -X POST \ - -H "Content-Type: application/json" \ - -H "$AUTH_HEADER" \ - -H "Origin: ${{ inputs.hydra_instance }}" \ - -d '{"jobsets": ["${{ inputs.hydra_project }}:${{ inputs.hydra_jobset }}"]}' \ - "${{ inputs.hydra_instance }}/api/push") - - if [[ $response == *"\"submitted\":true"* ]]; then - echo "Hydra build triggered successfully" - else - echo "Failed to trigger Hydra build" - echo "Response: $response" - exit 1 - fi diff --git a/.github/actions/wait-for-hydra-build.yml b/.github/actions/wait-for-hydra-build.yml deleted file mode 100644 index fd72a46..0000000 --- a/.github/actions/wait-for-hydra-build.yml +++ /dev/null @@ -1,91 +0,0 @@ -name: 'Wait for Hydra Build' -description: 'Waits for a Hydra build to complete and returns the build status' -inputs: - hydra_instance: - description: 'URL of the Hydra instance' - required: true - hydra_project: - description: 'Name of the Hydra project' - required: true - hydra_jobset: - description: 'Name of the Hydra jobset' - required: true - hydra_username: - description: 'Username for Hydra authentication' - required: true - hydra_password: - description: 'Password for Hydra authentication' - required: true - max_attempts: - description: 'Maximum number of attempts to check build status' - required: false - default: '60' - wait_interval: - description: 'Interval in seconds between status checks' - required: false - default: '120' - -outputs: - build_success: - description: 'Whether the build succeeded (true) or failed (false)' - value: ${{ steps.wait-for-build.outputs.build_success }} - -runs: - using: "composite" - steps: - - name: Wait for Hydra build - id: wait-for-build - shell: bash - run: | - AUTH_HEADER="Authorization: Basic $(echo -n '${{ inputs.hydra_username }}:${{ inputs.hydra_password }}' | base64)" - attempt=0 - max_attempts=${{ inputs.max_attempts }} - wait_interval=${{ inputs.wait_interval }} - - while [ $attempt -lt $max_attempts ]; do - echo "Attempt $((attempt + 1))/$max_attempts" - - response=$(curl -s -H "$AUTH_HEADER" \ - "${{ inputs.hydra_instance }}/api/jobsets?project=${{ inputs.hydra_project }}") - - jobset=$(echo "$response" | jq -r '.[] | select(.name == "${{ inputs.hydra_jobset }}")') - - if [ -z "$jobset" ]; then - echo "Jobset ${{ inputs.hydra_jobset }} not found. Waiting..." - sleep $wait_interval - attempt=$((attempt + 1)) - continue - fi - - nrscheduled=$(echo "$jobset" | jq -r '.nrscheduled') - nrfailed=$(echo "$jobset" | jq -r '.nrfailed') - nrsucceeded=$(echo "$jobset" | jq -r '.nrsucceeded') - nrtotal=$(echo "$jobset" | jq -r '.nrtotal') - - echo "Status: nrscheduled=$nrscheduled, nrfailed=$nrfailed, nrsucceeded=$nrsucceeded, nrtotal=$nrtotal" - - if [ "$nrtotal" = "0" ]; then - echo "Build not started yet. Waiting..." - elif [ "$nrfailed" != "0" ]; then - echo "build_success=false" >> $GITHUB_OUTPUT - echo "Build failed" - exit 0 - elif [ "$nrsucceeded" = "$nrtotal" ] && [ "$nrtotal" != "0" ]; then - echo "build_success=true" >> $GITHUB_OUTPUT - echo "Build succeeded" - exit 0 - elif [ "$nrscheduled" = "0" ] && [ "$nrsucceeded" != "0" ] && [ "$nrsucceeded" = "$nrtotal" ]; then - echo "build_success=true" >> $GITHUB_OUTPUT - echo "Build succeeded" - exit 0 - else - echo "Build in progress. Waiting..." - fi - - sleep $wait_interval - attempt=$((attempt + 1)) - done - - echo "build_success=false" >> $GITHUB_OUTPUT - echo "Timeout reached. Build considered failed." - exit 1 diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml index 427b5d8..7d25da9 100644 --- a/.github/workflows/update.yml +++ b/.github/workflows/update.yml @@ -39,7 +39,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v3 with: - fetch-depth: 0 + fetch-depth: 0 # Fetch all history for all branches and tags - name: Install Nix uses: cachix/install-nix-action@v30 @@ -53,6 +53,8 @@ jobs: git diff if [[ -n $(git status -s) ]]; then echo "CHANGED=true" >> $GITHUB_OUTPUT + echo "Changes detected:" + git status -s else echo "CHANGED=false" >> $GITHUB_OUTPUT echo "No changes detected." @@ -68,7 +70,6 @@ jobs: - name: Create Pull Request if: steps.update-flake.outputs.CHANGED == 'true' - id: create-pr env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | @@ -77,38 +78,114 @@ jobs: --base main \ --head ${{ env.BRANCH_NAME }} + - name: Get Hydra session token + id: hydra-session + run: | + response=$(curl -X POST -i \ + '${{ env.HYDRA_INSTANCE }}/login' \ + -H 'accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Origin: ${{ env.HYDRA_INSTANCE }}' \ + -d '{ + "username": "${{ secrets.HYDRA_USERNAME }}", + "password": "${{ secrets.HYDRA_PASSWORD }}" + }') + session_cookie=$(echo "$response" | grep -i 'set-cookie' | sed -n 's/.*hydra_session=\([^;]*\).*/\1/p') + echo "SESSION_COOKIE=$session_cookie" >> $GITHUB_OUTPUT + - name: Create Hydra jobset if: steps.update-flake.outputs.CHANGED == 'true' - uses: ./.github/actions/create-hydra-jobset - with: - hydra_instance: ${{ env.HYDRA_INSTANCE }} - hydra_project: ${{ env.HYDRA_PROJECT }} - hydra_jobset: ${{ env.HYDRA_JOBSET }} - hydra_username: ${{ secrets.HYDRA_USERNAME }} - hydra_password: ${{ secrets.HYDRA_PASSWORD }} - flake_uri: "github:${{ github.repository }}/${{ env.BRANCH_NAME }}" - description: "PR #${{ steps.create-pr.outputs.pr_number }} - Auto-update flake dependencies" + env: + SESSION_COOKIE: ${{ steps.hydra-session.outputs.SESSION_COOKIE }} + run: | + curl -X PUT -H "Content-Type: application/json" \ + -H "Cookie: hydra_session=$SESSION_COOKIE" \ + -d '{ + "enabled": 1, + "visible": false, + "keepnr": 3, + "schedulingshares": 100, + "checkinterval": 60, + "description": "PR #${{ github.event.pull_request.number }} - Auto-update flake dependencies", + "flake": "github:${{ github.repository }}/${{ env.BRANCH_NAME }}", + "type": 1 + }' \ + "${{ env.HYDRA_INSTANCE }}/jobset/${{ env.HYDRA_PROJECT }}/${{ env.HYDRA_JOBSET }}" - name: Trigger Hydra build if: steps.update-flake.outputs.CHANGED == 'true' - uses: ./.github/actions/trigger-hydra-build - with: - hydra_instance: ${{ env.HYDRA_INSTANCE }} - hydra_project: ${{ env.HYDRA_PROJECT }} - hydra_jobset: ${{ env.HYDRA_JOBSET }} - hydra_username: ${{ secrets.HYDRA_USERNAME }} - hydra_password: ${{ secrets.HYDRA_PASSWORD }} + env: + SESSION_COOKIE: ${{ steps.hydra-session.outputs.SESSION_COOKIE }} + run: | + curl -X POST -H "Content-Type: application/json" \ + -H "Cookie: hydra_session=$SESSION_COOKIE" \ + -H "Origin: ${{ env.HYDRA_INSTANCE }}" \ + -d '{"jobsets": ["${{ env.HYDRA_PROJECT }}:${{ env.HYDRA_JOBSET }}"]}' \ + "${{ env.HYDRA_INSTANCE }}/api/push" - name: Wait for Hydra build if: steps.update-flake.outputs.CHANGED == 'true' id: wait-for-build - uses: ./.github/actions/wait-for-hydra-build - with: - hydra_instance: ${{ env.HYDRA_INSTANCE }} - hydra_project: ${{ env.HYDRA_PROJECT }} - hydra_jobset: ${{ env.HYDRA_JOBSET }} - hydra_username: ${{ secrets.HYDRA_USERNAME }} - hydra_password: ${{ secrets.HYDRA_PASSWORD }} + env: + SESSION_COOKIE: ${{ steps.hydra-session.outputs.SESSION_COOKIE }} + run: | + max_attempts=60 # 30 minutes (30 * 2 minutes) + attempt=0 + build_status="unknown" + set -e # Exit immediately if a command exits with a non-zero status + while [ $attempt -lt $max_attempts ]; do + echo "Attempt $((attempt + 1))/$max_attempts" + response=$(curl -s -H "Cookie: hydra_session=$SESSION_COOKIE" \ + "${{ env.HYDRA_INSTANCE }}/api/jobsets?project=${{ env.HYDRA_PROJECT }}") + jobset=$(echo "$response" | jq -r '.[] | select(.name == "${{ env.HYDRA_JOBSET }}")') + + if [ -z "$jobset" ]; then + echo "Jobset ${{ env.HYDRA_JOBSET }} not found. Waiting..." + sleep 120 + attempt=$((attempt + 1)) + continue + fi + + + nrscheduled=$(echo "$jobset" | jq -r '.nrscheduled') + nrfailed=$(echo "$jobset" | jq -r '.nrfailed') + nrsucceeded=$(echo "$jobset" | jq -r '.nrsucceeded') + nrtotal=$(echo "$jobset" | jq -r '.nrtotal') + + echo "Status: nrscheduled=$nrscheduled, nrfailed=$nrfailed, nrsucceeded=$nrsucceeded, nrtotal=$nrtotal" + + if [ "$nrtotal" = "0" ]; then + echo "Build not started yet. Waiting..." + elif [ "$nrfailed" != "0" ]; then + build_status="failed" + break + elif [ "$nrsucceeded" = "$nrtotal" ] && [ "$nrtotal" != "0" ]; then + build_status="succeeded" + break + elif [ "$nrscheduled" = "0" ] && [ "$nrsucceeded" != "0" ] && [ "$nrsucceeded" = "$nrtotal" ]; then + build_status="succeeded" + break + else + echo "Build in progress. Waiting..." + fi + + sleep 120 # Wait for 2 minutes before checking again + attempt=$((attempt + 1)) + done + + if [ "$build_status" = "unknown" ]; then + echo "Timeout reached. Considering build as failed." + build_status="failed" + fi + + echo "BUILD_SUCCESS=$([ "$build_status" = "succeeded" ] && echo "true" || echo "false")" >> $GITHUB_OUTPUT + if [ "$build_status" = "succeeded" ]; then + echo "Build succeeded!" + exit 0 + else + echo "Build failed or timed out." + exit 1 + fi - name: Approve PR if: steps.update-flake.outputs.CHANGED == 'true' && steps.wait-for-build.outputs.BUILD_SUCCESS == 'true' @@ -166,26 +243,113 @@ jobs: echo "No changes detected." fi + - name: Get Hydra session token + id: hydra-session + run: | + response=$(curl -X POST -i \ + '${{ env.HYDRA_INSTANCE }}/login' \ + -H 'accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Origin: ${{ env.HYDRA_INSTANCE }}' \ + -d '{ + "username": "${{ secrets.HYDRA_USERNAME }}", + "password": "${{ secrets.HYDRA_PASSWORD }}" + }') + session_cookie=$(echo "$response" | grep -i 'set-cookie' | sed -n 's/.*hydra_session=\([^;]*\).*/\1/p') + echo "SESSION_COOKIE=$session_cookie" >> $GITHUB_OUTPUT + + - name: Create Hydra jobset + if: steps.update-flake.outputs.CHANGED == 'true' + env: + SESSION_COOKIE: ${{ steps.hydra-session.outputs.SESSION_COOKIE }} + run: | + curl -X PUT -H "Content-Type: application/json" \ + -H "Cookie: hydra_session=$SESSION_COOKIE" \ + -d '{ + "enabled": 1, + "visible": false, + "keepnr": 3, + "schedulingshares": 100, + "checkinterval": 60, + "description": "PR #${{ github.event.pull_request.number }} - Auto-update flake dependencies", + "flake": "github:${{ github.repository }}/${{ env.BRANCH_NAME }}", + "type": 1 + }' \ + "${{ env.HYDRA_INSTANCE }}/jobset/${{ env.HYDRA_PROJECT }}/${{ env.HYDRA_JOBSET }}" + - name: Trigger Hydra build if: steps.update-flake.outputs.CHANGED == 'true' - uses: ./.github/actions/trigger-hydra-build - with: - hydra_instance: ${{ env.HYDRA_INSTANCE }} - hydra_project: ${{ env.HYDRA_PROJECT }} - hydra_jobset: ${{ env.HYDRA_JOBSET }} - hydra_username: ${{ secrets.HYDRA_USERNAME }} - hydra_password: ${{ secrets.HYDRA_PASSWORD }} + env: + SESSION_COOKIE: ${{ steps.hydra-session.outputs.SESSION_COOKIE }} + run: | + curl -X POST -H "Content-Type: application/json" \ + -H "Cookie: hydra_session=$SESSION_COOKIE" \ + -H "Origin: ${{ env.HYDRA_INSTANCE }}" \ + -d '{"jobsets": ["${{ env.HYDRA_PROJECT }}:${{ env.HYDRA_JOBSET }}"]}' \ + "${{ env.HYDRA_INSTANCE }}/api/push" - name: Wait for Hydra build if: steps.update-flake.outputs.CHANGED == 'true' id: wait-for-build - uses: ./.github/actions/wait-for-hydra-build - with: - hydra_instance: ${{ env.HYDRA_INSTANCE }} - hydra_project: ${{ env.HYDRA_PROJECT }} - hydra_jobset: ${{ env.HYDRA_JOBSET }} - hydra_username: ${{ secrets.HYDRA_USERNAME }} - hydra_password: ${{ secrets.HYDRA_PASSWORD }} + env: + SESSION_COOKIE: ${{ steps.hydra-session.outputs.SESSION_COOKIE }} + run: | + max_attempts=60 # 30 minutes (30 * 2 minutes) + attempt=0 + build_status="unknown" + set -e # Exit immediately if a command exits with a non-zero status + while [ $attempt -lt $max_attempts ]; do + echo "Attempt $((attempt + 1))/$max_attempts" + response=$(curl -s -H "Cookie: hydra_session=$SESSION_COOKIE" \ + "${{ env.HYDRA_INSTANCE }}/api/jobsets?project=${{ env.HYDRA_PROJECT }}") + jobset=$(echo "$response" | jq -r '.[] | select(.name == "${{ env.HYDRA_JOBSET }}")') + + if [ -z "$jobset" ]; then + echo "Jobset ${{ env.HYDRA_JOBSET }} not found. Waiting..." + sleep 120 + attempt=$((attempt + 1)) + continue + fi + + nrscheduled=$(echo "$jobset" | jq -r '.nrscheduled') + nrfailed=$(echo "$jobset" | jq -r '.nrfailed') + nrsucceeded=$(echo "$jobset" | jq -r '.nrsucceeded') + nrtotal=$(echo "$jobset" | jq -r '.nrtotal') + + echo "Status: nrscheduled=$nrscheduled, nrfailed=$nrfailed, nrsucceeded=$nrsucceeded, nrtotal=$nrtotal" + + if [ "$nrtotal" = "0" ]; then + echo "Build not started yet. Waiting..." + elif [ "$nrfailed" != "0" ]; then + build_status="failed" + break + elif [ "$nrsucceeded" = "$nrtotal" ] && [ "$nrtotal" != "0" ]; then + build_status="succeeded" + break + elif [ "$nrscheduled" = "0" ] && [ "$nrsucceeded" != "0" ] && [ "$nrsucceeded" = "$nrtotal" ]; then + build_status="succeeded" + break + else + echo "Build in progress. Waiting..." + fi + + sleep 120 # Wait for 2 minutes before checking again + attempt=$((attempt + 1)) + done + + if [ "$build_status" = "unknown" ]; then + echo "Timeout reached. Considering build as failed." + build_status="failed" + fi + + echo "BUILD_SUCCESS=$([ "$build_status" = "succeeded" ] && echo "true" || echo "false")" >> $GITHUB_OUTPUT + if [ "$build_status" = "succeeded" ]; then + echo "Build succeeded!" + exit 0 + else + echo "Build failed or timed out." + exit 1 + fi - name: Approve PR if: steps.update-flake.outputs.CHANGED == 'true' && steps.wait-for-build.outputs.BUILD_SUCCESS == 'true'