diff --git a/.github/LICENSE.actionlint-matcher.json b/.github/LICENSE.actionlint-matcher.json new file mode 100644 index 000000000..a6c940dcb --- /dev/null +++ b/.github/LICENSE.actionlint-matcher.json @@ -0,0 +1,22 @@ +https://raw.githubusercontent.com/rhysd/actionlint/0ba78a0/LICENSE.txt + +the MIT License + +Copyright (c) 2021 rhysd + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR +THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/.github/actionlint-matcher.json b/.github/actionlint-matcher.json new file mode 100644 index 000000000..4613e1617 --- /dev/null +++ b/.github/actionlint-matcher.json @@ -0,0 +1,17 @@ +{ + "problemMatcher": [ + { + "owner": "actionlint", + "pattern": [ + { + "regexp": "^(?:\\x1b\\[\\d+m)?(.+?)(?:\\x1b\\[\\d+m)*:(?:\\x1b\\[\\d+m)*(\\d+)(?:\\x1b\\[\\d+m)*:(?:\\x1b\\[\\d+m)*(\\d+)(?:\\x1b\\[\\d+m)*: (?:\\x1b\\[\\d+m)*(.+?)(?:\\x1b\\[\\d+m)* \\[(.+?)\\]$", + "file": 1, + "line": 2, + "column": 3, + "message": 4, + "code": 5 + } + ] + } + ] +} diff --git a/.github/actionlint.yml b/.github/actionlint.yml new file mode 100644 index 000000000..d69044187 --- /dev/null +++ b/.github/actionlint.yml @@ -0,0 +1,3 @@ +self-hosted-runner: + labels: + - arm64-runner # Not actually self-hosted. diff --git a/.github/workflows/actionlint.yml b/.github/workflows/actionlint.yml new file mode 100644 index 000000000..8343da79f --- /dev/null +++ b/.github/workflows/actionlint.yml @@ -0,0 +1,28 @@ +name: Lint GitHub Actions +on: + push: + paths: ['.github/workflows/**', '.github/actions/**', '.github/actionlint.yml'] +jobs: + actionlint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + show-progress: false + - id: install + env: + VERSION: '1.7.0' + run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/b6b7a2901eb4fa4bae2e6d8f9b6edd1a37b3cca7/scripts/download-actionlint.bash) "$VERSION" . + - name: Run actionlint + env: + ACTIONLINT: '${{ steps.install.outputs.executable }}' + run: | + echo "::add-matcher::.github/actionlint-matcher.json" + # TODO: move -ignores inline or to actionlint.yml once + # https://www.github.com/rhysd/actionlint/issues/237 and/or + # https://www.github.com/rhysd/actionlint/issues/217 is fixed. + # TODO: remove -ignore "property .runner. is not defined" once + # https://www.github.com/rhysd/actionlint/issues/77 is fixed. + "$ACTIONLINT" -color \ + -ignore "property .runner. is not defined" \ + -ignore "property .repository_visibility. is not defined" diff --git a/.github/workflows/autorelease-rubygem.yml b/.github/workflows/autorelease-rubygem.yml index 1fcfe648b..30c4c30c7 100644 --- a/.github/workflows/autorelease-rubygem.yml +++ b/.github/workflows/autorelease-rubygem.yml @@ -1,17 +1,3 @@ -# USAGE -# ----- -# -# on: -# workflow_dispatch: {} -# schedule: -# - cron: '00 13 * * 2' -# -# jobs: -# autorelease: -# uses: alphagov/govuk-infrastructure/.github/workflows/autorelease-rubygem.yml@main -# secrets: -# GH_TOKEN: ${{ secrets.GOVUK_CI_GITHUB_API_TOKEN }} - name: Auto-release Rubygem on: @@ -42,6 +28,7 @@ jobs: - name: "Determine HEAD of default branch" id: fetch_default_branch_head run: echo "sha=$(git ls-remote origin HEAD | cut -f 1)" >> "$GITHUB_OUTPUT" + - if: github.sha == steps.fetch_default_branch_head.outputs.sha name: "Auto-release rubygem" env: @@ -50,47 +37,52 @@ jobs: run: | set -euo pipefail - CURR_VERSION=$(ruby -e "puts eval(File.read('$GEM_NAME.gemspec')).version") - NEXT_VERSION=$(echo $CURR_VERSION | cut -d . -f1).$(echo $CURR_VERSION | cut -d . -f2).$(( $(echo $CURR_VERSION | cut -d . -f3) + 1 )) - BRANCH="release-$NEXT_VERSION" - PR_TITLE="Release v$NEXT_VERSION" - PR_DESCRIPTION="This is an automated PR to bump the version number to $NEXT_VERSION. This is a patch-level bump, as the only changes since v$CURR_VERSION are dependency updates made by Dependabot." + curr_ver=$(ruby -r rubygems -e "puts Gem::Specification::load('$GEM_NAME.gemspec').version") + IFS=. read -ra ver_parts <<< "$curr_ver" + (( ver_parts[2]++ )) # Increment the patch version. + next_ver=$(printf "%d.%d.%d" "${ver_parts[@]}") + branch="release-$next_ver" + pr_title="Release v$next_ver" + pr_desc="This is an automated PR to bump the version number to $next_ver. This is a patch-level bump, as the only changes since v$curr_ver are dependency updates made by Dependabot." - if ! [ -f CHANGELOG.md ]; then - echo "CHANGELOG.md does not exist. Exiting." + if ! [[ -r CHANGELOG.md ]]; then + echo "CHANGELOG.md not found or not readable. Exiting." exit 0 fi - if ! grep -qR --include "version.rb" --include "*.gemspec" $CURR_VERSION; then - echo "Can't find version.rb or *.gemspec containing the string '$CURR_VERSION'. Exiting." + if ! grep -qR --include "version.rb" --include "*.gemspec" "$curr_ver"; then + echo "Can't find version.rb or *.gemspec containing the string '$curr_ver'. Exiting." exit 0 fi - if git ls-remote --exit-code origin refs/heads/$BRANCH > /dev/null; then - echo "Branch 'release-$NEXT_VERSION' already exists on the remote. Exiting." + if git ls-remote --exit-code origin "refs/heads/$branch" > /dev/null; then + echo "Branch 'release-$next_ver' already exists on the remote. Exiting." exit 0 fi - if [ "$(git log v$CURR_VERSION..main --no-merges --format=format:%an | sort | uniq)" != "dependabot[bot]" ]; then + if [ "$(git log "v$curr_ver..main" --no-merges --format=format:%an | sort | uniq)" != "dependabot[bot]" ]; then echo "Gem has no unreleased changes, or those changes include commits from users other than Dependabot. Exiting." exit 0 fi - find . -type f \( -iname version.rb -o -iname *.gemspec \) -exec sed -i "s/$CURR_VERSION/$NEXT_VERSION/g" {} \; + curr_ver_regex=$(printf "%d\\\.%d\\\.%d" "${ver_parts[@]}") + find . -type f \( -iname version.rb -o -iname "*.gemspec" \) -exec sed -i "s/$curr_ver_regex/$next_ver/g" {} \; - printf "# $NEXT_VERSION\n\n* Update dependencies\n\n" | cat - CHANGELOG.md > NEW_CHANGELOG.md + printf "# %s\n\n* Update dependencies\n\n" "$next_ver" > NEW_CHANGELOG.md + cat CHANGELOG.md >> NEW_CHANGELOG.md mv NEW_CHANGELOG.md CHANGELOG.md git config --global user.name "GOV.UK Continuous Integration User" git config --global user.email "govuk-ci@users.noreply.github.com" - git checkout -b $BRANCH + git checkout -b "$branch" git add . git reset -- vendor/bundle - git commit -m "$PR_TITLE" - git push origin $BRANCH + git commit -m "$pr_title" + git push origin "$branch" + + gh pr create -H "$branch" --title "$pr_title" --body "$pr_desc" - gh pr create -H $BRANCH --title "$PR_TITLE" --body "$PR_DESCRIPTION" - if: github.sha != steps.fetch_default_branch_head.outputs.sha name: "Skip release: commit is not HEAD of default branch" run: | diff --git a/.github/workflows/brakeman.yml b/.github/workflows/brakeman.yml index ac81c761e..6a5d9ed6a 100644 --- a/.github/workflows/brakeman.yml +++ b/.github/workflows/brakeman.yml @@ -20,34 +20,20 @@ jobs: with: bundler-cache: true - - name: Run Brakeman SARIF + - name: Run Brakeman continue-on-error: true - if: ${{ github.repository_visibility == 'public' }} - run: bundle exec brakeman . --except CheckRenderInline --quiet -f sarif >> brakeman.sarif - - - name: Run Brakeman JSON - continue-on-error: true - if: ${{ github.repository_visibility == 'private' || github.repository_visibility == 'internal' }} - run: bundle exec brakeman . --except CheckRenderInline --quiet -f json >> brakeman.json - - - name: Check if SARIF file exists - id: sarif_check run: | - if [ -f brakeman.sarif ]; then - echo "sarif_exists=true" >> $GITHUB_OUTPUT - else - echo "sarif_exists=false" >> $GITHUB_OUTPUT - fi + bundle exec brakeman . --except CheckRenderInline --quiet \ + -o brakeman.json -o brakeman.sarif - - name: Upload SARIF to Github Code Scanning - if: steps.sarif_check.outputs.sarif_exists == 'true' + - name: Upload SARIF to GitHub + if: github.repository_visibility == 'public' uses: github/codeql-action/upload-sarif@v3 with: sarif_file: brakeman.sarif - - name: Upload JSON result as artifact - if: steps.sarif_check.outputs.sarif_exists == 'false' - uses: actions/upload-artifact@v2 + - name: Upload JSON results + uses: actions/upload-artifact@v4 with: name: brakeman-json path: brakeman.json diff --git a/.github/workflows/build-and-push-image.yml b/.github/workflows/build-and-push-image.yml index 92cd1a853..53184145e 100644 --- a/.github/workflows/build-and-push-image.yml +++ b/.github/workflows/build-and-push-image.yml @@ -54,7 +54,7 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - run: echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT + - run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" id: local-head - name: Determine image tags diff --git a/.github/workflows/build-and-push-multiarch-image.yml b/.github/workflows/build-and-push-multiarch-image.yml index 3c8ac072d..f1b244c7c 100644 --- a/.github/workflows/build-and-push-multiarch-image.yml +++ b/.github/workflows/build-and-push-multiarch-image.yml @@ -44,23 +44,25 @@ jobs: id-token: write contents: read steps: - - name: Install Docker (Github ARM Only) - if: ${{ matrix.runner == 'arm64-runner' }} + # TODO: remove this step once GitHub's ARM runner image comes with Docker. + - name: Install Docker (GitHub ARM Only) + if: matrix.runner == 'arm64-runner' + env: + DEBIAN_FRONTEND: noninteractive run: | - sudo apt-get update - sudo apt-get -y install ca-certificates curl + sudo apt-get update -qq + sudo apt-get install -qq --no-install-recommends acl ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ - $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ - sudo tee /etc/apt/sources.list.d/docker.list > /dev/null - sudo apt-get update - sudo apt-get -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin - sudo usermod -a -G docker $USER - sudo apt-get install acl - sudo setfacl --modify user:$USER:rw /var/run/docker.sock + $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \ + | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null + sudo apt-get update -qq + sudo apt-get install -qq --no-install-recommends docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin + sudo usermod -aG docker "$USER" + sudo setfacl --modify "user:$USER:rw" /var/run/docker.sock - uses: actions/checkout@v4 with: @@ -68,7 +70,7 @@ jobs: show-progress: false - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v4.0.1 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: "arn:aws:iam::172025368201:role/github_action_ecr_push" aws-region: eu-west-1 @@ -82,7 +84,7 @@ jobs: - uses: docker/setup-buildx-action@v3 - - run: echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT + - run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" id: local-head - name: Generate Image Metadata @@ -112,10 +114,11 @@ jobs: cache-to: type=gha,scope=build-${{ matrix.arch }},mode=max - id: export-digests + env: + DIGEST: "${{ steps.build-image.outputs.digest }}" run: | mkdir -p /tmp/digests - digest="${{steps.build-image.outputs.digest }}" - touch "/tmp/digests/${digest#sha256:}" + touch "/tmp/digests/${DIGEST#sha256:}" - id: upload-digests uses: actions/upload-artifact@v4 @@ -135,23 +138,25 @@ jobs: id-token: write contents: read steps: - - name: Install Docker (Github ARM Only) - if: ${{ matrix.runner == 'arm64-runner' }} + # TODO: remove this step once GitHub's ARM runner image comes with Docker. + - name: Install Docker (GitHub ARM Only) + if: matrix.runner == 'arm64-runner' + env: + DEBIAN_FRONTEND: noninteractive run: | - sudo apt-get update - sudo apt-get -y install ca-certificates curl + sudo apt-get update -qq + sudo apt-get install -qq --no-install-recommends acl ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ - $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ - sudo tee /etc/apt/sources.list.d/docker.list > /dev/null - sudo apt-get update - sudo apt-get -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin - sudo usermod -a -G docker $USER - sudo apt-get install acl - sudo setfacl --modify user:$USER:rw /var/run/docker.sock + $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \ + | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null + sudo apt-get update -qq + sudo apt-get install -qq --no-install-recommends docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin + sudo usermod -aG docker "$USER" + sudo setfacl --modify "user:$USER:rw" /var/run/docker.sock - name: Download Digests uses: actions/download-artifact@v4 @@ -162,11 +167,11 @@ jobs: - uses: docker/setup-buildx-action@v3 - - run: echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT + - run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" id: local-head - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v4.0.1 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: "arn:aws:iam::172025368201:role/github_action_ecr_push" aws-region: eu-west-1 @@ -192,11 +197,17 @@ jobs: type=raw,priority=400,value=${{ needs.build-and-push-image.outputs.localSha }},enable=${{ !startsWith(inputs.gitRef, 'v') }} - name: Create Manifest Lists + env: + IMAGEREF_PREFIX: '${{ steps.login-ecr.outputs.registry }}/${{ inputs.ecrRepositoryName }}' working-directory: /tmp/digests run: | - docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ - $(printf '${{ steps.login-ecr.outputs.registry }}/${{ inputs.ecrRepositoryName }}@sha256:%s ' *) + tag_args=$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") + printf -v sources "${IMAGEREF_PREFIX}@sha256:%s " * + # shellcheck disable=SC2086 # Intentional word-splitting on $tag_args and $sources. + docker buildx imagetools create $tag_args $sources - name: Inspect Images + env: + IMAGEREF: '${{ steps.login-ecr.outputs.registry }}/${{ inputs.ecrRepositoryName }}:${{ steps.meta.outputs.version }}' run: | - docker buildx imagetools inspect ${{ steps.login-ecr.outputs.registry }}/${{ inputs.ecrRepositoryName }}:${{ steps.meta.outputs.version }} + docker buildx imagetools inspect "$IMAGEREF" diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 492de4e25..8788a9ba5 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -16,7 +16,7 @@ on: environment: description: 'Environment to deploy to' required: false - default: 'integration' + default: integration type: string secrets: WEBHOOK_TOKEN: @@ -39,11 +39,12 @@ jobs: GH_TOKEN: ${{ secrets.GH_TOKEN }} GITHUB_TEAM: gov-uk-production-deploy GITHUB_USER: ${{ github.triggering_actor }} + TRIGGERING_ACTOR: ${{ github.triggering_actor }} run: | - TEAM_MEMBERSHIP=$(gh api orgs/alphagov/teams/${GITHUB_TEAM}/memberships/${GITHUB_USER} -q .state || echo "false") + TEAM_MEMBERSHIP=$(gh api "orgs/alphagov/teams/$GITHUB_TEAM/memberships/$GITHUB_USER" -q .state || echo false) - if ! [[ "${TEAM_MEMBERSHIP}" = "active" || "${ENVIRONMENT}" = 'integration' ]]; then - echo '::error title=Insufficient permissions to deploy::User ${{ github.triggering_actor }} needs to be a member of the GOV.UK Production Deploy team' + if ! [[ "$TEAM_MEMBERSHIP" = active || "$ENVIRONMENT" = integration ]]; then + echo "::error title=Insufficient permissions to deploy::User $TRIGGERING_ACTOR needs to be a member of the GOV.UK Production Deploy team" exit 1 fi diff --git a/.github/workflows/mirror-repos.yml b/.github/workflows/mirror-repos.yml index e88779e40..1755510ed 100644 --- a/.github/workflows/mirror-repos.yml +++ b/.github/workflows/mirror-repos.yml @@ -38,6 +38,7 @@ jobs: GH_TOKEN: ${{ github.token }} GITHUB_REPOS: ${{ steps.get-repos.outputs.github-repos }} run: | + # shellcheck disable=SC2086 # Intentional word-splitting on $GITHUB_REPOS. for repo in ${GITHUB_REPOS}; do git config --global credential.helper '!aws codecommit credential-helper $@' git config --global credential.UseHttpPath true diff --git a/.github/workflows/publish-rubygem.yml b/.github/workflows/publish-rubygem.yml index 3d1ce8962..8e9a569ca 100644 --- a/.github/workflows/publish-rubygem.yml +++ b/.github/workflows/publish-rubygem.yml @@ -1,31 +1,3 @@ -# USAGE -# ----- -# -# on: [push, pull_request] -# -# jobs: -# test: -# runs-on: ubuntu-latest -# steps: -# - uses: actions/checkout@v4 -# with: -# show-progress: false -# - uses: ruby/setup-ruby@v1 -# with: -# bundler-cache: true -# - run: bundle exec rake -# -# publish: -# needs: test -# if: github.ref == 'refs/heads/main' -# permissions: -# contents: write -# uses: alphagov/govuk-infrastructure/.github/workflows/publish-rubygem.yaml@main -# secrets: -# GEM_HOST_API_KEY: ${{ secrets.ALPHAGOV_RUBYGEMS_API_KEY }} - -# REUSABLE WORKFLOW -# ----------------- name: Publish a Rubygem on: @@ -62,22 +34,22 @@ jobs: GEM_NAME: ${{ inputs.gem_name }} GEM_HOST_API_KEY: ${{ secrets.GEM_HOST_API_KEY }} run: | - LOCAL_VERSION=$(ruby -e "puts eval(File.read('$GEM_NAME.gemspec')).version") - REMOTE_VERSION=$(gem list --exact --remote $GEM_NAME) - if [ "$REMOTE_VERSION" != "$GEM_NAME (${LOCAL_VERSION})" ]; then - gem build ${GEM_NAME}.gemspec - gem push "${GEM_NAME}-${LOCAL_VERSION}.gem" + local_version=$(ruby -r rubygems -e "puts Gem::Specification::load('$GEM_NAME.gemspec').version") + remote_version=$(gem list --exact --remote "$GEM_NAME") + if [[ "$remote_version" != "$GEM_NAME (${local_version})" ]]; then + gem build "${GEM_NAME}.gemspec" + gem push "${GEM_NAME}-${local_version}.gem" else - echo "Skipping gem publish because version (${LOCAL_VERSION}) is already published" + echo "::notice title=Gem version already published::Skipping gem publish because version (${local_version}) is already published" fi - if ! git ls-remote --tags --exit-code origin v${LOCAL_VERSION}; then - git tag v${LOCAL_VERSION} + if ! git ls-remote --tags --exit-code origin "v${local_version}"; then + git tag "v${local_version}" git push --tags else - echo "Skipping git tagging because tag (v${LOCAL_VERSION}) already exists" + echo "::notice title=Tag already exists::Skipping git tagging because tag (v${local_version}) already exists" fi - if: github.sha != steps.fetch_default_branch_head.outputs.sha name: "Skip publish: commit is not HEAD of default branch" run: | - echo "Skipping publish because commit (${GITHUB_SHA}) isn't the HEAD of the default branch (${{ steps.fetch_default_branch_head.outputs.sha }})" + echo "Skipping publish because commit ($GITHUB_SHA) isn't the HEAD of the default branch ($DEFAULT_BRANCH_HEAD_SHA)" >> "$GITHUB_JOB_SUMMARY" diff --git a/.github/workflows/set-automatic-deploys.yml b/.github/workflows/set-automatic-deploys.yml index 671c0097d..9ad207048 100644 --- a/.github/workflows/set-automatic-deploys.yml +++ b/.github/workflows/set-automatic-deploys.yml @@ -6,7 +6,6 @@ on: automaticDeploysEnabled: description: 'Configures whether automatic deployments are enabled' required: true - default: true type: boolean appName: required: false @@ -37,9 +36,9 @@ jobs: GITHUB_TEAM: gov-uk-production-deploy GITHUB_USER: ${{ github.triggering_actor }} run: | - TEAM_MEMBERSHIP=$(gh api orgs/alphagov/teams/${GITHUB_TEAM}/memberships/${GITHUB_USER} -q .state || echo "false") + TEAM_MEMBERSHIP=$(gh api "orgs/alphagov/teams/${GITHUB_TEAM}/memberships/${GITHUB_USER}" -q .state || echo false) - if ! [[ "${TEAM_MEMBERSHIP}" = "active" || "${ENVIRONMENT}" = 'integration' ]]; then + if ! [[ "${TEAM_MEMBERSHIP}" = active || "${ENVIRONMENT}" = integration ]]; then echo "::error title=Insufficient permissions to deploy::User ${GITHUB_USER} needs to be a member of the ${GITHUB_TEAM} team" exit 1 fi