ci: Refactor get_cirrusci_freebsd script to GitHub action
This should make it more reliable and also easier to re-use, if we need to. Resolves #2555
This commit is contained in:
+2
-9
@@ -2,23 +2,16 @@ freebsd_instance:
|
|||||||
image_family: freebsd-14-0
|
image_family: freebsd-14-0
|
||||||
|
|
||||||
build_task:
|
build_task:
|
||||||
|
# Don't change this name without adjusting .github/workflows/build.yaml
|
||||||
name: Build FreeBSD (Stack)
|
name: Build FreeBSD (Stack)
|
||||||
install_script: pkg install -y postgresql16-client hs-stack git
|
install_script: pkg install -y postgresql16-client hs-stack git
|
||||||
|
|
||||||
# This also includes nix and cabal related files, because the
|
|
||||||
# Github Actions build workflow will run on those and the
|
|
||||||
# "Fetch from FreeBSD" job should not fail.
|
|
||||||
only_if: |
|
only_if: |
|
||||||
$CIRRUS_TAG != '' || $CIRRUS_BRANCH == 'main' || $CIRRUS_BRANCH =~ 'v*' ||
|
$CIRRUS_TAG != '' || $CIRRUS_BRANCH == 'main' || $CIRRUS_BRANCH =~ 'v*' ||
|
||||||
changesInclude(
|
changesInclude(
|
||||||
'.github/workflows/build.yaml',
|
'.github/workflows/build.yaml',
|
||||||
'.github/actions/setup-nix/**',
|
'.github/actions/artifact-from-cirrus/**',
|
||||||
'.github/scripts/**',
|
|
||||||
'.github/*',
|
|
||||||
'*.nix',
|
|
||||||
'nix/**',
|
|
||||||
'.cirrus.yml',
|
'.cirrus.yml',
|
||||||
'cabal.project*',
|
|
||||||
'postgrest.cabal',
|
'postgrest.cabal',
|
||||||
'stack.yaml*',
|
'stack.yaml*',
|
||||||
'**.hs'
|
'**.hs'
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
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_suite_found=1" >> "$GITHUB_OUTPUT"
|
||||||
|
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?"
|
||||||
|
echo "check_suite_found=0" >> "$GITHUB_OUTPUT"
|
||||||
|
- name: Find task by name
|
||||||
|
id: find-task
|
||||||
|
if: steps.check-suite.outputs.check_suite_found
|
||||||
|
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)"
|
||||||
|
curl --no-progress-meter --fail -o "${archive}" \
|
||||||
|
"https://api.cirrus-ci.com/v1/artifact/task/$(get_external_id)/${{ inputs.download }}.zip"
|
||||||
|
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@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
|
||||||
|
with:
|
||||||
|
name: ${{ inputs.upload }}
|
||||||
|
path: ${{ steps.download.outputs.artifacts }}
|
||||||
|
if-no-files-found: error
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
# Get the FreeBSD PostgREST executable built by CirrusCI for the given GITHUB_COMMIT in GITHUB_REPOSITORY
|
|
||||||
|
|
||||||
# We use the GitHub API for 'check suites' to find the corresponding CirrusCI job, see:
|
|
||||||
# https://docs.github.com/en/rest/reference/checks#list-check-suites-for-a-git-reference
|
|
||||||
|
|
||||||
cirrus_artifact_name=bin
|
|
||||||
gh_auth_header="Authorization: Bearer $GITHUB_TOKEN"
|
|
||||||
gh_accept_header="Accept: application/vnd.github.v3+json"
|
|
||||||
|
|
||||||
get_gh_check_runs_url() {
|
|
||||||
gh_checks_list_url="https://api.github.com/repos/$GITHUB_REPOSITORY/commits/$GITHUB_COMMIT/check-suites"
|
|
||||||
>&2 echo "Getting list of check-suites from $gh_checks_list_url ..."
|
|
||||||
curl -s --fail -H "$gh_auth_header" -H "$gh_accept_header" "$gh_checks_list_url" \
|
|
||||||
| jq -r '.check_suites[] | select(.app.slug == "cirrus-ci") | .check_runs_url'
|
|
||||||
}
|
|
||||||
|
|
||||||
wait_for_cirrusci() {
|
|
||||||
>&2 echo "Waiting to CirrusCI run to complete (two hours maximum)..."
|
|
||||||
for _ in $(seq 1 120); do
|
|
||||||
gh_check_runs_url="$(get_gh_check_runs_url)"
|
|
||||||
if [ -z "$gh_check_runs_url" ]; then
|
|
||||||
echo "CirrusCI task has not started, yet. Waiting..."
|
|
||||||
else
|
|
||||||
echo "Checking for CirrusCI task status at $gh_check_runs_url ..."
|
|
||||||
status=$(curl -s --fail -H "$gh_auth_header" "$gh_check_runs_url" | jq -r '.check_runs[] | .status')
|
|
||||||
if [ "$status" == "completed" ]; then
|
|
||||||
break
|
|
||||||
else
|
|
||||||
echo "CirrusCI task is still $status, waiting..."
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
sleep 60
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# The CirrusCI taskid can change if a new check run is started for the same commit,
|
|
||||||
# e.g. when pushing both a branch and tag. We make sure that we have the very
|
|
||||||
# latest taskid by re-loading the 'gh_check_runs_url' and the 'check run' itself.
|
|
||||||
get_cirrus_taskid() {
|
|
||||||
gh_check_runs_url="$(get_gh_check_runs_url)"
|
|
||||||
>&2 echo "Getting the CirrusCI task id from $gh_check_runs_url ..."
|
|
||||||
curl --fail -H "$gh_auth_header" -H "$gh_accept_header" "$gh_check_runs_url" \
|
|
||||||
| jq -r '.check_runs[] | .external_id'
|
|
||||||
}
|
|
||||||
|
|
||||||
download_artifact() {
|
|
||||||
cirrus_task_id="$(get_cirrus_taskid)"
|
|
||||||
cirrus_artifact_url="https://api.cirrus-ci.com/v1/artifact/task/$cirrus_task_id/$cirrus_artifact_name.zip"
|
|
||||||
>&2 echo "Attemping to download the CirrusCI artifact from $cirrus_artifact_url ..."
|
|
||||||
curl --fail "$cirrus_artifact_url" -o freebsd.zip
|
|
||||||
}
|
|
||||||
|
|
||||||
wait_for_cirrusci
|
|
||||||
download_artifact
|
|
||||||
|
|
||||||
echo "Unpacking executable..."
|
|
||||||
unzip freebsd.zip -d .
|
|
||||||
rm -rf freebsd.zip
|
|
||||||
@@ -144,18 +144,12 @@ jobs:
|
|||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||||
- name: Get FreeBSD executable from CirrusCI
|
- uses: ./.github/actions/artifact-from-cirrus
|
||||||
env:
|
|
||||||
# GITHUB_SHA does weird things for pull request, so we roll our own:
|
|
||||||
GITHUB_COMMIT: ${{ github.event.pull_request.head.sha || github.sha }}
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
run: .github/get_cirrusci_freebsd
|
|
||||||
- name: Save executable as artifact
|
|
||||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
|
|
||||||
with:
|
with:
|
||||||
name: postgrest-freebsd-x64
|
token: ${{ github.token }}
|
||||||
path: postgrest
|
task: Build FreeBSD (Stack)
|
||||||
if-no-files-found: error
|
download: bin
|
||||||
|
upload: postgrest-freebsd-x64
|
||||||
|
|
||||||
|
|
||||||
cabal:
|
cabal:
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
, hlint
|
, hlint
|
||||||
, hsie
|
, hsie
|
||||||
, nixpkgs-fmt
|
, nixpkgs-fmt
|
||||||
, shellcheck
|
|
||||||
, silver-searcher
|
, silver-searcher
|
||||||
, statix
|
, statix
|
||||||
, stylish-haskell
|
, stylish-haskell
|
||||||
@@ -58,10 +57,6 @@ let
|
|||||||
workingDir = "/";
|
workingDir = "/";
|
||||||
}
|
}
|
||||||
''
|
''
|
||||||
echo "Linting bash scripts..."
|
|
||||||
${shellcheck}/bin/shellcheck \
|
|
||||||
.github/get_cirrusci_freebsd \
|
|
||||||
|
|
||||||
echo "Linting workflows..."
|
echo "Linting workflows..."
|
||||||
${actionlint}/bin/actionlint
|
${actionlint}/bin/actionlint
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user