name: CI on: push: branches: - main - v[0-9]+ tags: - devel - v* pull_request: branches: - main - v[0-9]+ concurrency: group: ${{ github.workflow }}-${{ github.ref }} # Terminate all previous runs of the same workflow for pull requests cancel-in-progress: "${{ github.event_name == 'pull_request' }}" jobs: Lint-Style: name: Lint & check code style runs-on: ubuntu-22.04 steps: - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Setup Nix Environment uses: ./.github/actions/setup-nix with: tools: style - name: Run linter (check locally with `nix-shell --run postgrest-lint`) run: postgrest-lint - name: Run style check (auto-format with `nix-shell --run postgrest-style`) run: postgrest-style-check Test-Nix: name: Test (Nix) runs-on: ubuntu-22.04 defaults: run: # Hack for enabling color output, see: # https://github.com/actions/runner/issues/241#issuecomment-842566950 shell: script -qec "bash --noprofile --norc -eo pipefail {0}" steps: - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Setup Nix Environment uses: ./.github/actions/setup-nix with: tools: tests - name: Run coverage (IO tests and Spec tests against PostgreSQL 15) run: postgrest-coverage - name: Upload coverage to codecov uses: codecov/codecov-action@5ecb98a3c6b747ed38dc09f787459979aebb39be # v4.3.1 with: files: ./coverage/codecov.json token: ${{ secrets.CODECOV_TOKEN }} - name: Run doctests if: always() run: nix-shell --run postgrest-test-doctests - name: Check the spec tests for idempotence if: always() run: postgrest-test-spec-idempotence Test-Pg-Nix: strategy: fail-fast: false matrix: pgVersion: [9.6, 10, 11, 12, 13, 14, 15, 16] name: Test PG ${{ matrix.pgVersion }} (Nix) runs-on: ubuntu-22.04 defaults: run: # Hack for enabling color output, see: # https://github.com/actions/runner/issues/241#issuecomment-842566950 shell: script -qec "bash --noprofile --norc -eo pipefail {0}" steps: - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Setup Nix Environment uses: ./.github/actions/setup-nix with: tools: tests withTools - name: Run spec tests if: always() run: postgrest-with-postgresql-${{ matrix.pgVersion }} postgrest-test-spec - name: Run IO tests if: always() run: postgrest-with-postgresql-${{ matrix.pgVersion }} -f test/io/fixtures.sql postgrest-test-io -vv Test-Memory-Nix: name: Test memory (Nix) runs-on: ubuntu-22.04 steps: - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Setup Nix Environment uses: ./.github/actions/setup-nix with: tools: memory - name: Run memory tests run: postgrest-test-memory Build-Static-Nix: name: Build Linux static (Nix) runs-on: ubuntu-22.04 steps: - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Setup Nix Environment uses: ./.github/actions/setup-nix with: tools: tests - name: Build static executable run: nix-build -A postgrestStatic - name: Check static executable run: postgrest-check-static result/bin/postgrest - name: Save built executable as artifact uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: postgrest-linux-static-x64 path: result/bin/postgrest if-no-files-found: error - name: Build Docker image run: nix-build -A docker.image --out-link postgrest-docker.tar.gz - name: Save built Docker image as artifact uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: postgrest-docker-x64 path: postgrest-docker.tar.gz if-no-files-found: error Build-Macos-Nix: name: Build MacOS (Nix) runs-on: macos-12 steps: - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Setup Nix Environment uses: ./.github/actions/setup-nix - name: Build everything run: | nix-build Build-Stack: strategy: fail-fast: false matrix: include: - name: Linux runs-on: ubuntu-22.04 cache: | ~/.stack .stack-work artifact: postgrest-ubuntu-x64 - name: MacOS runs-on: macos-12 cache: | ~/.stack .stack-work artifact: postgrest-macos-x64 - name: Windows runs-on: windows-2022 cache: | ~\AppData\Roaming\stack ~\AppData\Local\Programs\stack .stack-work deps: Add-Content $env:GITHUB_PATH $env:PGBIN artifact: postgrest-windows-x64 name: Build ${{ matrix.name }} (Stack) runs-on: ${{ matrix.runs-on }} steps: - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Stack working files cache uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 with: path: ${{ matrix.cache }} key: cache-stack-${{ runner.os }}-${{ hashFiles('stack.yaml.lock') }} - name: Install dependencies if: ${{ matrix.deps }} run: ${{ matrix.deps }} - name: Build with Stack run: stack build --local-bin-path result --copy-bins - name: Save built executable as artifact uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: ${{ matrix.artifact }} path: | result/postgrest result/postgrest.exe if-no-files-found: error Get-FreeBSD-CirrusCI: name: Get FreeBSD build from CirrusCI runs-on: ubuntu-22.04 steps: - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - uses: ./.github/actions/artifact-from-cirrus with: token: ${{ github.token }} task: Build FreeBSD (Stack) download: bin upload: postgrest-freebsd-x64 Build-Cabal: strategy: matrix: ghc: ['9.0.2', '9.2.4'] fail-fast: false name: Build Linux (Cabal, GHC ${{ matrix.ghc }}) runs-on: ubuntu-22.04 steps: - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Workaround runner image issue # https://github.com/actions/runner-images/issues/7061 run: sudo chown -R "$USER" /usr/local/.ghcup - name: ghcup run: | ghcup install ghc ${{ matrix.ghc }} ghcup set ghc ${{ matrix.ghc }} - name: Copy cabal.project & fix caching run: | mkdir ~/.cabal cp cabal.project.non-nix cabal.project - name: Cache uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 with: path: | ~/.cabal/packages ~/.cabal/store dist-newstyle key: cache-cabal-${{ runner.os }}-${{ matrix.ghc }}-${{ hashFiles('**/*.cabal', '**/cabal.project') }} restore-keys: | cache-cabal-${{ runner.os }}-${{ matrix.ghc }}- - name: Install dependencies run: | cabal update cabal build --only-dependencies --enable-tests --enable-benchmarks - name: Build run: cabal build --enable-tests --enable-benchmarks all Build-Cabal-Arm: strategy: matrix: ghc: ['9.2.4'] fail-fast: false name: Build aarch64 (Cabal, GHC ${{ matrix.ghc }}) if: "${{ github.event_name == 'push' }}" runs-on: ubuntu-22.04 outputs: remotepath: ${{ steps.Remote-Dir.outputs.remotepath }} env: GITHUB_COMMIT: ${{ github.sha }} GHC_VERSION: ${{ matrix.ghc }} steps: - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - id: Remote-Dir name: Unique directory name for the remote build run: echo "remotepath=postgrest-build-$(uuidgen)" >> "$GITHUB_OUTPUT" - name: Copy script files to the remote server uses: appleboy/scp-action@master with: host: ${{ secrets.SSH_ARM_HOST }} username: ubuntu key: ${{ secrets.SSH_ARM_PRIVATE_KEY }} fingerprint: ${{ secrets.SSH_ARM_FINGERPRINT }} source: ".github/scripts/arm/*" target: ${{ steps.Remote-Dir.outputs.remotepath }} strip_components: 3 - name: Build ARM uses: appleboy/ssh-action@master env: REMOTE_DIR: ${{ steps.Remote-Dir.outputs.remotepath }} with: host: ${{ secrets.SSH_ARM_HOST }} username: ubuntu key: ${{ secrets.SSH_ARM_PRIVATE_KEY }} fingerprint: ${{ secrets.SSH_ARM_FINGERPRINT }} command_timeout: 120m script_stop: true envs: GITHUB_COMMIT,REMOTE_DIR,GHC_VERSION script: bash ~/$REMOTE_DIR/build.sh "$GITHUB_COMMIT" "$REMOTE_DIR" "GHC_VERSION" - name: Download binaries from remote server uses: nicklasfrahm/scp-action@main with: direction: download host: ${{ secrets.SSH_ARM_HOST }} username: ubuntu key: ${{ secrets.SSH_ARM_PRIVATE_KEY }} fingerprint: ${{ secrets.SSH_ARM_FINGERPRINT }} source: "${{ steps.Remote-Dir.outputs.remotepath }}/result.tar.xz" target: "result.tar.xz" - name: Extract downloaded binaries run: tar -xvf result.tar.xz && rm result.tar.xz - name: Save aarch64 executable as artifact uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: postgrest-ubuntu-aarch64 path: result/postgrest if-no-files-found: error Tag-Release: name: Tag Release if: startsWith(github.ref, 'refs/heads/') permissions: contents: write runs-on: ubuntu-22.04 needs: - Lint-Style - Test-Nix - Test-Pg-Nix - Test-Memory-Nix - Build-Static-Nix - Build-Stack - Get-FreeBSD-CirrusCI - Build-Cabal-Arm steps: - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 with: ssh-key: ${{ secrets.POSTGREST_SSH_KEY }} - name: Tag latest commit run: | cabal_version="$(grep -oP '^version:\s*\K.*' postgrest.cabal)" if [[ "$cabal_version" == *.*.* ]]; then git fetch --tags if [ -z "$(git tag --list "v$cabal_version")" ]; then git tag "v$cabal_version" git push origin "v$cabal_version" fi else git tag -f "devel" git push -f origin "devel" fi Prepare-Release: name: Prepare release if: startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-22.04 needs: - Lint-Style - Test-Nix - Test-Pg-Nix - Test-Memory-Nix - Build-Static-Nix - Build-Stack - Get-FreeBSD-CirrusCI - Build-Cabal-Arm steps: - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Check the version to be released run: | cabal_version="$(grep -oP '^version:\s*\K.*' postgrest.cabal)" if [ "${GITHUB_REF_NAME}" != "devel" ] && [ "${GITHUB_REF_NAME}" != "v$cabal_version" ]; then echo "Tagged version ($GITHUB_REF_NAME) does not match the one in postgrest.cabal (v$cabal_version). Aborting release..." exit 1 fi - name: Identify changes from CHANGELOG.md run: | if [ "${GITHUB_REF_NAME}" == "devel" ]; then echo "Getting unreleased changes..." sed -n "1,/## Unreleased/d;/## \[/q;p" CHANGELOG.md > CHANGES.md else version="$(grep -oP '^version:\s*\K.*' postgrest.cabal)" echo "Propper release, getting changes for version $version ..." sed -n "1,/## \[$version\]/d;/## \[/q;p" CHANGELOG.md > CHANGES.md fi echo "Relevant extract from CHANGELOG.md:" cat CHANGES.md - name: Save CHANGES.md as artifact uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: release-changes path: CHANGES.md if-no-files-found: error Release-GitHub: name: Release on GitHub permissions: contents: write runs-on: ubuntu-22.04 needs: Prepare-Release steps: - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Download all artifacts uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: path: artifacts - name: Create release bundle with archives for all builds run: | find artifacts -type f -iname postgrest -exec chmod +x {} \; mkdir -p release-bundle tar cJvf "release-bundle/postgrest-${GITHUB_REF_NAME}-linux-static-x64.tar.xz" \ -C artifacts/postgrest-linux-static-x64 postgrest tar cJvf "release-bundle/postgrest-${GITHUB_REF_NAME}-macos-x64.tar.xz" \ -C artifacts/postgrest-macos-x64 postgrest tar cJvf "release-bundle/postgrest-${GITHUB_REF_NAME}-freebsd-x64.tar.xz" \ -C artifacts/postgrest-freebsd-x64 postgrest tar cJvf "release-bundle/postgrest-${GITHUB_REF_NAME}-ubuntu-aarch64.tar.xz" \ -C artifacts/postgrest-ubuntu-aarch64 postgrest zip "release-bundle/postgrest-${GITHUB_REF_NAME}-windows-x64.zip" \ artifacts/postgrest-windows-x64/postgrest.exe - name: Save release bundle uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: release-bundle path: release-bundle if-no-files-found: error - name: Publish release on GitHub env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | echo "Releasing version ${GITHUB_REF_NAME} on GitHub..." if [ "${GITHUB_REF_NAME}" == "devel" ]; then # To replace the existing release, we must first delete the old assets, # then modify the release, then add the new assets. gh release view devel --json assets \ | jq -r '.assets[] | .name' \ | xargs -rn1 \ gh release delete-asset -y devel gh release edit devel \ -t devel \ --verify-tag \ -F artifacts/release-changes/CHANGES.md \ --prerelease gh release upload --clobber devel release-bundle/* else gh release create "${GITHUB_REF_NAME}" \ -t "${GITHUB_REF_NAME}" \ --verify-tag \ -F artifacts/release-changes/CHANGES.md \ release-bundle/* fi Release-Docker: name: Release on Docker Hub runs-on: ubuntu-22.04 needs: - Prepare-Release env: DOCKER_REPO: ${{ vars.DOCKER_REPO }} DOCKER_USER: ${{ vars.DOCKER_USER }} DOCKER_PASS: ${{ secrets.DOCKER_PASS }} steps: - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Download Docker image uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: postgrest-docker-x64 - name: Publish images on Docker Hub run: | docker login -u "$DOCKER_USER" -p "$DOCKER_PASS" docker load -i postgrest-docker.tar.gz docker tag postgrest:latest "$DOCKER_REPO/postgrest:${GITHUB_REF_NAME}" docker push "$DOCKER_REPO/postgrest:${GITHUB_REF_NAME}" # Only tag 'latest' for full releases if [ "${GITHUB_REF_NAME}" != "devel" ]; then echo "Pushing to 'latest' tag for full release of ${GITHUB_REF_NAME} ..." docker tag postgrest:latest "$DOCKER_REPO"/postgrest:latest docker push "$DOCKER_REPO"/postgrest:latest else echo "Skipping push to 'latest' tag for pre-release..." fi # TODO: Enable dockerhub description update again, once a solution for the permission problem is found: # https://github.com/docker/hub-feedback/issues/1927 # - name: Update descriptions on Docker Hub # env: # DOCKER_PASS: ${{ secrets.DOCKER_PASS }} # run: | # if [[ -z "$ISPRERELEASE" ]]; then # echo "Updating description on Docker Hub..." # postgrest-release-dockerhub-description # else # echo "Skipping updating description for pre-release..." # fi Release-Docker-Arm: name: Release Arm Builds on Docker Hub runs-on: ubuntu-22.04 needs: - Build-Cabal-Arm - Release-Docker env: GITHUB_COMMIT: ${{ github.sha }} DOCKER_REPO: ${{ vars.DOCKER_REPO }} DOCKER_USER: ${{ vars.DOCKER_USER }} DOCKER_PASS: ${{ secrets.DOCKER_PASS }} steps: - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Publish images for ARM builds on Docker Hub uses: appleboy/ssh-action@master env: REMOTE_DIR: ${{ needs.Build-Cabal-Arm.outputs.remotepath }} with: host: ${{ secrets.SSH_ARM_HOST }} username: ubuntu key: ${{ secrets.SSH_ARM_PRIVATE_KEY }} fingerprint: ${{ secrets.SSH_ARM_FINGERPRINT }} script_stop: true envs: GITHUB_COMMIT,DOCKER_REPO,DOCKER_USER,DOCKER_PASS,REMOTE_DIR,GITHUB_REF_NAME script: bash ~/$REMOTE_DIR/docker-publish.sh "$GITHUB_COMMIT" "$DOCKER_REPO" "$DOCKER_USER" "$DOCKER_PASS" "$REMOTE_DIR" "$GITHUB_REF_NAME" Clean-Arm-Server: name: Remove copied files from server needs: - Build-Cabal-Arm - Release-Docker-Arm if: success() || needs.Build-Cabal-Arm.result == 'failure' || needs.Build-Cabal-Arm.result == 'cancelled' || (needs.Build-Cabal-Arm.result == 'success' && !startsWith(github.ref, 'refs/tags/v')) runs-on: ubuntu-22.04 env: REMOTE_DIR: ${{ needs.Build-Cabal-Arm.outputs.remotepath }} steps: - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Remove uploaded files from server uses: appleboy/ssh-action@master with: host: ${{ secrets.SSH_ARM_HOST }} username: ubuntu key: ${{ secrets.SSH_ARM_PRIVATE_KEY }} fingerprint: ${{ secrets.SSH_ARM_FINGERPRINT }} envs: REMOTE_DIR script: rm -rf $REMOTE_DIR