name: Artifact from Cirrus description: Waits for a specific Cirrus CI run to complete, then downloads the artifact and uploads it to the current workflow. This will silently succeed if Cirrus CI did not schedule a task within 2 minutes. inputs: download: description: Name of Artifact to download from Cirrus CI required: true task: description: Name of Cirrus Task required: true token: description: GitHub Token required: true upload: description: Name of Artifact to upload on GitHub Actions required: true runs: using: composite steps: - shell: bash run: echo "GH_TOKEN=${{ inputs.token }}" >> "$GITHUB_ENV" - name: Wait for Check Suite to be created id: check-suite env: # GITHUB_SHA does weird things for pull request, so we roll our own: COMMIT: ${{ github.event.pull_request.head.sha || github.sha }} shell: bash run: | get_check_runs_url() { gh api "repos/{owner}/{repo}/commits/${COMMIT}/check-suites" \ | jq -r '.check_suites[] | select(.app.slug == "cirrus-ci") | .check_runs_url' } for _ in $(seq 1 12); do check_runs_url="$(get_check_runs_url)" if [ -z "$check_runs_url" ]; then echo "Cirrus CI task has not started, yet. Waiting..." sleep 10 else echo "check_runs_url=$check_runs_url" >> "$GITHUB_OUTPUT" exit 0 fi done >&2 echo "Cirrus CI check suite not found. Is Cirrus CI enabled for this repo?" - name: Find task by name id: find-task if: steps.check-suite.outputs.check_runs_url shell: bash run: | get_number_of_tasks() { gh api "${{ steps.check-suite.outputs.check_runs_url }}" \ | jq -r '.check_runs | map(select(.name == "${{ inputs.task }}")) | length' } tasks="$(get_number_of_tasks)" case "$tasks" in 0) echo "Task not found, assuming it's skipped intentionally..." exit 0 ;; 1) echo "task_found=1" >> "$GITHUB_OUTPUT" exit 0 ;; *) >&2 echo "More than 1 task with the same name found. Don't know what to do..." exit 1 ;; esac - name: Wait for Cirrus CI to complete task if: steps.find-task.outputs.task_found shell: bash run: | get_conclusion() { gh api "${{ steps.check-suite.outputs.check_runs_url }}" \ | jq -r '.check_runs[] | select(.name == "${{ inputs.task }}" and .status == "completed") | .conclusion' } while true; do conclusion="$(get_conclusion)" if [ -z "$conclusion" ]; then echo "Cirrus CI task has not completed, yet. Waiting..." sleep 30 else if [ "$conclusion" == "success" ]; then break else exit 1 fi fi done - name: Download artifact from Cirrus CI if: steps.find-task.outputs.task_found id: download shell: bash run: | get_external_id() { gh api "${{ steps.check-suite.outputs.check_runs_url }}" \ | jq -er '.check_runs[] | select(.name == "${{ inputs.task }}") | .external_id' } archive="$(mktemp)" artifacts="$(mktemp -d)" until curl --no-progress-meter --fail -o "${archive}" \ "https://api.cirrus-ci.com/v1/artifact/task/$(get_external_id)/${{ inputs.download }}.zip" do # This happens when a tag is pushed on the same commit. In this case the # job is immediately marked as "completed" for us, so we end up here after a few # seconds - but the actual Cirrus CI task is still running and didn't produce its artifact, yet. echo "Artifact not found on Cirrus CI, yet. Waiting..." sleep 30 done unzip "${archive}" -d "${artifacts}" echo "artifacts=${artifacts}" >> "$GITHUB_OUTPUT" - name: Save artifact to GitHub Actions if: steps.find-task.outputs.task_found uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: ${{ inputs.upload }} path: ${{ steps.download.outputs.artifacts }} if-no-files-found: error