diff --git a/.github/workflows/generate-dependabot-file.yml b/.github/workflows/generate-dependabot-file.yml new file mode 100644 index 0000000..7f70144 --- /dev/null +++ b/.github/workflows/generate-dependabot-file.yml @@ -0,0 +1,44 @@ +name: Generate dependabot file + +on: + schedule: + - cron: "40 22 * * 6" + push: + branches: + - main + paths: + - '.github/workflows/generate-dependabot-file.yml' + - 'scripts/generate-dependabot-file.sh' + workflow_dispatch: + +permissions: {} + +defaults: + run: + shell: bash + +jobs: + create-and-commit-dependabot-file: + permissions: + contents: write + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - name: Generate file + run: bash ./scripts/generate-dependabot-file.sh + - name: Commit changes to GitHub + run: bash ./scripts/git-setup.sh + - run: bash ./scripts/git-commit.sh .github + - run: bash ./scripts/git-pull-request.sh dependabot + env: + SECRET: ${{ secrets.GITHUB_TOKEN }} + - name: Slack failure notification + uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 + with: + payload: | + {"blocks":[{"type": "section","text": {"type": "mrkdwn","text": ":no_entry: Failed GitHub Action:"}},{"type": "section","fields":[{"type": "mrkdwn","text": "*Workflow:*\n<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|${{ github.workflow }}>"},{"type": "mrkdwn","text": "*Job:*\n${{ github.job }}"},{"type": "mrkdwn","text": "*Repo:*\n${{ github.repository }}"}]}]} + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK + if: ${{ failure() }} \ No newline at end of file diff --git a/scripts/generate-dependabot-file.sh b/scripts/generate-dependabot-file.sh new file mode 100644 index 0000000..9092d45 --- /dev/null +++ b/scripts/generate-dependabot-file.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +set -euo pipefail + +dependabot_file=.github/dependabot.yml + +# Get a list of Terraform folders +all_tf_folders=`find . -type f -name '*.tf' | sed 's#/[^/]*$##' | sed 's/.\///'| sort | uniq` +all_env_test_folders=`find . -type f -name 'go.mod' | sed 's#/[^/]*$##' | sed 's/.\///'| sort | uniq` +echo +echo "All TF folders" +echo $all_tf_folders +echo +echo "All environment test folders" +echo $all_env_test_folders + +echo "Writing dependabot.yml file" +# Creates a dependabot file to avoid having to manually add each new TF folder or go.mod file +# Add any additional fixed entries in this top section + cat > $dependabot_file << EOL +# This file is auto-generated here, do not manually amend. +# https://github.com/ministryofjustice/modernisation-platform/blob/main/scripts/generate-dependabot.sh + +version: 2 + +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + # Dependabot doesn't currently support wildcard or multiple directory declarations within + # a dependabot configuration, so we need to add all directories individually + # See: github.com/dependabot/dependabot-core/issues/2178 +EOL + +for folder in $all_tf_folders +do +echo "Generating entry for ${folder}" +echo " - package-ecosystem: \"terraform\"" >> $dependabot_file +echo " directory: \"/${folder}\"" >> $dependabot_file +echo " schedule:" >> $dependabot_file +echo " interval: \"daily\"" >> $dependabot_file +done + +for folder in $all_env_test_folders +do +echo "Generating entry for ${folder}" +echo " - package-ecosystem: \"gomod\"" >> $dependabot_file +echo " directory: \"/${folder}\"" >> $dependabot_file +echo " schedule:" >> $dependabot_file +echo " interval: \"daily\"" >> $dependabot_file +done \ No newline at end of file diff --git a/scripts/git-commit.sh b/scripts/git-commit.sh new file mode 100644 index 0000000..0869f5a --- /dev/null +++ b/scripts/git-commit.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +if [ ! -z "$2" ]; then + GIT_DIR=$2 + cd $GIT_DIR + GITHUB_REPOSITORY=$(basename `git rev-parse --show-toplevel`) + GITHUB_REPOSITORY="ministryofjustice/$GITHUB_REPOSITORY" + TOKEN=$TERRAFORM_GITHUB_TOKEN +else + TOKEN=$GITHUB_TOKEN +fi + +branch="date-$(date +%s)" +commit_message="Workflow: created files in ${1}" + +git checkout -b "$branch" +git add "$1" +git commit -m "$commit_message" + +commit_success=$? +if [ $commit_success -ne 0 ]; then + echo "Nothing to commit" + exit 0 +fi + +git remote rm origin || true +git remote add origin "https://${TOKEN}@github.com/${GITHUB_REPOSITORY}.git" +git push -u origin "$branch" + +git status \ No newline at end of file diff --git a/scripts/git-pull-request.sh b/scripts/git-pull-request.sh new file mode 100644 index 0000000..f5e285e --- /dev/null +++ b/scripts/git-pull-request.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +if [ ! -z "$2" ]; then + GIT_DIR=$2 + cd $GIT_DIR + GITHUB_REPOSITORY=$(basename `git rev-parse --show-toplevel`) + GITHUB_REPOSITORY="ministryofjustice/$GITHUB_REPOSITORY" + SECRET=$TERRAFORM_GITHUB_TOKEN +fi + +# Define: repository URL, branch, title, and PR body +repository_url="https://api.github.com/repos/${GITHUB_REPOSITORY}/pulls" +pull_request_branch=$(git branch --show-current) +pull_request_title="New files for $1" +pull_request_body="> This PR was automatically created via a GitHub action workflow 🤖 + +This PR commits new files under $1." + +# Check if changes to create PR +if [ "$(git rev-parse main)" = "$(git rev-parse $pull_request_branch)" ]; then + echo "No difference in branches to create PR, exiting." + exit 0 +fi + +payload=$(echo "${pull_request_body}" | jq --arg branch "$pull_request_branch" --arg pr_title "$pull_request_title" -R --slurp '{ body: ., base: "main", head: $branch, title: $pr_title }') + +echo "${payload}" | curl \ + -s -X POST \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Authorization: token ${SECRET}" \ + -d @- $repository_url > /dev/null +ERRORCODE="${?}" +if [ ${ERRORCODE} -ne 0 ] +then + echo "ERROR: git-pull-request.sh exited with an error - Code:${ERRORCODE}" + exit 1 +fi \ No newline at end of file diff --git a/scripts/git-setup.sh b/scripts/git-setup.sh new file mode 100644 index 0000000..73b8010 --- /dev/null +++ b/scripts/git-setup.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +if [ ! -z "$1" ]; then + GIT_DIR=$1 +fi + +name=$(git config --get user.name) +email=$(git config --get user.email) + +if [ -z "$name" ]; then + git config --global user.name "modernisation-platform-ci" +fi + +if [ -z "$email" ]; then + git config --global user.email "modernisation-platform+github@digital.justice.gov.uk" +fi \ No newline at end of file