From 8552c66c1e1413d567b24cf33e718afb7abebdf9 Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Sat, 18 Jan 2025 19:22:51 +0100 Subject: [PATCH] ci: Use FreeBSD VM instead of cirrus --- .cirrus.yml | 42 ------- .../actions/artifact-from-cirrus/action.yaml | 119 ------------------ .github/actions/run-anywhere/action.yaml | 35 ++++++ .github/workflows/build.yaml | 59 ++++----- 4 files changed, 58 insertions(+), 197 deletions(-) delete mode 100644 .cirrus.yml delete mode 100644 .github/actions/artifact-from-cirrus/action.yaml create mode 100644 .github/actions/run-anywhere/action.yaml diff --git a/.cirrus.yml b/.cirrus.yml deleted file mode 100644 index 5e8687c82..000000000 --- a/.cirrus.yml +++ /dev/null @@ -1,42 +0,0 @@ -freebsd_instance: - image_family: freebsd-14-3 - -build_task: - # Don't change this name without adjusting .github/workflows/build.yaml - name: Build FreeBSD (Stack) - install_script: pkg install -y postgresql16-client hs-stack git - - only_if: | - $CIRRUS_TAG != '' || $CIRRUS_BRANCH == 'main' || $CIRRUS_BRANCH =~ 'v*' || - changesInclude( - '.github/workflows/build.yaml', - '.github/actions/artifact-from-cirrus/**', - '.cirrus.yml', - 'postgrest.cabal', - 'stack.yaml*', - '**.hs' - ) - - stack_cache: - folders: /.stack - fingerprint_script: - - echo $CIRRUS_OS - - stack --version - - md5sum postgrest.cabal - - md5sum stack.yaml.lock - - stack_work_cache: - folders: .stack-work - fingerprint_script: - - echo $CIRRUS_OS - - stack --version - - md5sum postgrest.cabal - - md5sum stack.yaml.lock - - find main src -type f -iname '*.hs' -exec md5sum "{}" + - - build_script: | - stack build -j 1 --local-bin-path . --copy-bins - strip postgrest - - bin_artifacts: - path: postgrest diff --git a/.github/actions/artifact-from-cirrus/action.yaml b/.github/actions/artifact-from-cirrus/action.yaml deleted file mode 100644 index f550294d2..000000000 --- a/.github/actions/artifact-from-cirrus/action.yaml +++ /dev/null @@ -1,119 +0,0 @@ -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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: ${{ inputs.upload }} - path: ${{ steps.download.outputs.artifacts }} - if-no-files-found: error diff --git a/.github/actions/run-anywhere/action.yaml b/.github/actions/run-anywhere/action.yaml new file mode 100644 index 000000000..39cd25d53 --- /dev/null +++ b/.github/actions/run-anywhere/action.yaml @@ -0,0 +1,35 @@ +name: Run anywhere + +description: Runs the same code either in a VM or on the bare machine + +inputs: + vm: + description: Which VM to run on. + envs: + description: List of relevant environment variables, which might need to be copied into the VM. + prepare: + description: Code to run in a prepare step, e.g. installing dependencies. + run: + description: Code to run as the main action. + required: true + +runs: + using: composite + steps: + - if: ${{ inputs.vm == 'freebsd' }} + uses: vmactions/freebsd-vm@a6de9343ef5747433d9c25784c90e84998b9d69a # v1.4.6 + with: + envs: ${{ inputs.envs }} + prepare: ${{ inputs.prepare }} + # Work around https://github.com/vmactions/freebsd-vm/issues/59 + run: | + pw user add -n action -m + su action -c '${{ inputs.run }}' + - if: ${{ inputs.vm == '' }} + name: Prepare + shell: ${{ runner.os == 'Windows' && 'pwsh' || 'bash' }} + run: ${{ inputs.prepare }} + - if: ${{ inputs.vm == '' }} + name: Run + shell: ${{ runner.os == 'Windows' && 'pwsh' || 'bash' }} + run: ${{ inputs.run }} diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 7af47ac2c..dd66fa63d 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -98,64 +98,64 @@ jobs: fail-fast: false matrix: include: + - name: FreeBSD x86-64 + runs-on: ubuntu-24.04 + vm: freebsd + artifact: postgrest-freebsd-x86-64 + deps: pkg install -y postgresql16-client hs-stack + - name: MacOS aarch64 runs-on: macos-14 - cache: | - ~/.stack/pantry - ~/.stack/snapshots - ~/.stack/stack.sqlite3 artifact: postgrest-macos-aarch64 deps: brew link --force libpq - name: MacOS x86-64 runs-on: macos-15-intel - cache: | - ~/.stack/pantry - ~/.stack/snapshots - ~/.stack/stack.sqlite3 artifact: postgrest-macos-x86-64 deps: brew link --force libpq - name: Windows runs-on: windows-2022 - cache: | - C:\sr\pantry - C:\sr\snapshots - C:\sr\stack.sqlite3 deps: Add-Content $env:GITHUB_PATH $env:PGBIN artifact: postgrest-windows-x86-64 name: Stack - ${{ matrix.name }} runs-on: ${{ matrix.runs-on }} + env: + # Putting .stack in the working directory helps with moving this in and out of the FreeBSD VM. + STACK_ROOT: ${{ github.workspace }}/.stack steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: haskell-actions/setup@cd0d9bdd65b20557f41bea4dbe43d0b5fbbfe553 # v2.11.0 + - if: ${{ !matrix.vm }} + uses: haskell-actions/setup@cd0d9bdd65b20557f41bea4dbe43d0b5fbbfe553 # v2.11.0 with: # This must match the version in stack.yaml's resolver ghc-version: 9.10.3 enable-stack: true stack-no-global: true stack-setup-ghc: true - - name: Cache ~/.stack + - name: Cache .stack uses: ./.github/actions/cache-on-main with: - path: ${{ matrix.cache }} - prefix: stack + path: .stack + prefix: ${{ matrix.vm }}${{ matrix.vm && '-' }}stack suffix: ${{ hashFiles('postgrest.cabal', 'stack.yaml.lock') }} - name: Cache .stack-work uses: ./.github/actions/cache-on-main with: path: .stack-work save-prs: true - prefix: stack-work-${{ hashFiles('postgrest.cabal', 'stack.yaml.lock') }} + prefix: ${{ matrix.vm }}${{ matrix.vm && '-' }}stack-work-${{ hashFiles('postgrest.cabal', 'stack.yaml.lock') }} suffix: ${{ hashFiles('main/**/*.hs', 'src/**/*.hs') }} - - name: Install dependencies - if: matrix.deps - run: ${{ matrix.deps }} - name: Build with Stack - run: stack build --lock-file error-on-write --local-bin-path result --copy-bins - - name: Strip Executable - run: strip result/postgrest* + uses: ./.github/actions/run-anywhere + with: + vm: ${{ matrix.vm }} + envs: STACK_ROOT + prepare: ${{ matrix.deps }} + run: | + stack build --lock-file error-on-write --local-bin-path result --copy-bins + strip result/postgrest* - name: Save built executable as artifact uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: @@ -166,19 +166,6 @@ jobs: if-no-files-found: error - freebsd: - name: Stack - FreeBSD from CirrusCI - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: ./.github/actions/artifact-from-cirrus - with: - token: ${{ github.token }} - task: Build FreeBSD (Stack) - download: bin - upload: postgrest-freebsd-x86-64 - - cabal: strategy: matrix: