From 2853dec47ee42538f2475d5237ae754ce085eff7 Mon Sep 17 00:00:00 2001 From: Olzhas Arystanov Date: Sat, 30 Nov 2024 20:57:44 +0500 Subject: [PATCH] Add scheduled workflow for cruft updates --- README.md | 20 +++++ cookiecutter.json | 5 +- .../.github/workflows/cruft-updates.yml | 88 +++++++++++++++++++ 3 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 {{cookiecutter.repostory_name}}/.github/workflows/cruft-updates.yml diff --git a/README.md b/README.md index 398597e6..a45567dc 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,26 @@ pip install cruft More on cruft: +## Automatic cruft updates + +This template ships with a GitHub Actions workflow that will periodically (once a week) monitor changes in the template and automatically create a pull request with updates using `cruft`. + +### Setup + +The workflow requires permissions to create pull requests. +You can enable it by going to Repository Settings -> Actions -> General -> Allow GitHub Actions to create and approve pull requests. + +### Slack notifications (optional) + +The bot can send notifications to a Slack channel when a new pull request with updates is created. + +To enable this, you need to set two secrets in your repository: + +- `SLACK_BOT_TOKEN` (the token of your Slack app) +- `SLACK_CHANNEL_ID` (the ID of the channel where you want to receive notifications) + +If you don't have a Slack app, follow the [instructions here](https://github.com/slackapi/slack-github-action?tab=readme-ov-file#technique-2-slack-api-method) to create one. + ## License This project is licensed under the terms of the [BSD-3 License](/LICENSE) diff --git a/cookiecutter.json b/cookiecutter.json index e498ade9..d988bb98 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -49,5 +49,8 @@ "aws_staging_domain_name": "staging.{{ cookiecutter.aws_domain_name }}", "aws_ec2_ssh_key": "", "ci_use_linter": "y", - "ci_use_spellchecker": "y" + "ci_use_spellchecker": "y", + "_copy_without_render": [ + ".github/workflows/cruft-updates.yml" + ] } diff --git a/{{cookiecutter.repostory_name}}/.github/workflows/cruft-updates.yml b/{{cookiecutter.repostory_name}}/.github/workflows/cruft-updates.yml new file mode 100644 index 00000000..fb7c59a7 --- /dev/null +++ b/{{cookiecutter.repostory_name}}/.github/workflows/cruft-updates.yml @@ -0,0 +1,88 @@ +name: Update repository with Cruft +permissions: + contents: write + pull-requests: write +on: + schedule: + - cron: "0 2 * * 1" # Every Monday at 2am + workflow_dispatch: + +jobs: + update: + runs-on: ubuntu-latest + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install Cruft + run: pip3 install cruft + + - name: Check if update is available + continue-on-error: false + id: check + run: | + CHANGES=0 + if [ -f .cruft.json ]; then + if ! cruft check; then + CHANGES=1 + fi + else + echo "No .cruft.json file" + fi + + echo "has_changes=$CHANGES" >> "$GITHUB_OUTPUT" + + - name: Run update if available + if: steps.check.outputs.has_changes == '1' + run: | + git config --global user.email "updater@reef.pl" + git config --global user.name "Cruft Updater" + + cruft update --skip-apply-ask --refresh-private-variables + git restore --staged . + + - name: Check for .rej files + if: steps.check.outputs.has_changes == '1' + id: check_rej + run: | + REJ_FILES=$(find . -name "*.rej") + if [ -n "$REJ_FILES" ]; then + echo "has_rej_files=1" >> "$GITHUB_OUTPUT" + else + echo "has_rej_files=0" >> "$GITHUB_OUTPUT" + fi + + - name: Create pull request + if: steps.check.outputs.has_changes == '1' + id: create_pr + uses: peter-evans/create-pull-request@v7 + with: + token: ${{ secrets.GITHUB_TOKEN }} + add-paths: . + commit-message: "Apply new Cruft update" + branch: cruft/update + delete-branch: true + title: Cruft cookiecutter update + body: | + This is an autogenerated PR. + + ${{ steps.check_rej.outputs.has_rej_files == '1' && 'IMPORTANT: One or more `.rej` files have been detected, which means that some changes could not be applied automatically. Please RESOLVE them manually' || 'No conflicts detected' }} + + - name: Post to a Slack channel + if: steps.create_pr.outputs.pull-request-number && env.SLACK_BOT_TOKEN + uses: slackapi/slack-github-action@v2.0.0 + with: + method: chat.postMessage + token: ${{ env.SLACK_BOT_TOKEN }} + payload: | + channel: ${{ env.SLACK_CHANNEL_ID }} + text: | + cruft updates for `${{ github.repository }}`: + ${{ steps.create_pr.outputs.pull-request-url }} + ${{ steps.check_rej.outputs.has_rej_files == '1' && 'IMPORTANT: `.rej` files detected, conflicts need to be resolved' || 'Can be merged safely' }}