From 58addb3f2500e1c1659a2d0a62e50da5e9087dc3 Mon Sep 17 00:00:00 2001 From: "Patrick J. Roddy" Date: Fri, 5 Jul 2024 21:22:34 +0100 Subject: [PATCH] Add some composite actions (#18) Mimicking the set-up we have at https://github.com/UCL-MIRSG/.github/tree/main/actions. Required for @r-roker-ucl to add issues/PRs to project boards. --- .github/ISSUE_TEMPLATE/agile.yaml | 8 ++-- .github/ISSUE_TEMPLATE/workstream.yaml | 4 +- .github/workflows/links.yaml | 21 ++++++++++ .github/workflows/linting.yaml | 20 ++++++++++ .github/workflows/linting.yml | 34 ---------------- .github/workflows/tags.yaml | 51 ++++++++++++++++++++++++ .pre-commit-config.yaml | 44 +++++++++++++++++++-- actions/README.md | 5 +++ actions/add-to-project/README.md | 55 ++++++++++++++++++++++++++ actions/add-to-project/action.yml | 44 +++++++++++++++++++++ actions/links/README.md | 30 ++++++++++++++ actions/links/action.yml | 29 ++++++++++++++ actions/linting/README.md | 15 +++++++ actions/linting/action.yml | 33 ++++++++++++++++ renovate/README.md | 18 ++++----- 15 files changed, 358 insertions(+), 53 deletions(-) create mode 100644 .github/workflows/links.yaml create mode 100644 .github/workflows/linting.yaml delete mode 100644 .github/workflows/linting.yml create mode 100644 .github/workflows/tags.yaml create mode 100644 actions/README.md create mode 100644 actions/add-to-project/README.md create mode 100644 actions/add-to-project/action.yml create mode 100644 actions/links/README.md create mode 100644 actions/links/action.yml create mode 100644 actions/linting/README.md create mode 100644 actions/linting/action.yml diff --git a/.github/ISSUE_TEMPLATE/agile.yaml b/.github/ISSUE_TEMPLATE/agile.yaml index 97c71a9..cd2311b 100644 --- a/.github/ISSUE_TEMPLATE/agile.yaml +++ b/.github/ISSUE_TEMPLATE/agile.yaml @@ -8,8 +8,8 @@ body: label: Definition of Done / Acceptance Criteria description: What can someone see/do when this task is done. placeholder: >- - The export data is available in the xxx format, - including age of the patient at the time of imaging... + The export data is available in the xxx format, including age of the + patient at the time of imaging... validations: required: true - type: textarea @@ -33,8 +33,8 @@ body: attributes: label: Dependencies description: >- - Enter the github issue number(s) that the - requirement is dependent on, in the form `#1` + Enter the github issue number(s) that the requirement is dependent on, + in the form `#1` placeholder: "#1" validations: required: false diff --git a/.github/ISSUE_TEMPLATE/workstream.yaml b/.github/ISSUE_TEMPLATE/workstream.yaml index b3df386..f2277a4 100644 --- a/.github/ISSUE_TEMPLATE/workstream.yaml +++ b/.github/ISSUE_TEMPLATE/workstream.yaml @@ -16,7 +16,7 @@ body: label: Child issues description: What issues need to be completed for this issue to be done placeholder: >- - The export data is available in the xxx format, - including age of the patient at the time of imaging... + The export data is available in the xxx format, including age of the + patient at the time of imaging... validations: required: false diff --git a/.github/workflows/links.yaml b/.github/workflows/links.yaml new file mode 100644 index 0000000..67dc944 --- /dev/null +++ b/.github/workflows/links.yaml @@ -0,0 +1,21 @@ +--- +name: Links + +on: + push: + branches: + - main + - renovate/** + pull_request: + +jobs: + links: + runs-on: ubuntu-latest + timeout-minutes: 2 + steps: + - name: Checkout source + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 + + - uses: ./actions/links + with: + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/linting.yaml b/.github/workflows/linting.yaml new file mode 100644 index 0000000..0513fc4 --- /dev/null +++ b/.github/workflows/linting.yaml @@ -0,0 +1,20 @@ +--- +name: Linting + +on: + push: + branches: + - main + - renovate/** + pull_request: + +jobs: + linting: + runs-on: ubuntu-latest + steps: + - name: Checkout source + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 + + - uses: ./actions/linting + with: + pre-commit-config: ./.pre-commit-config.yaml diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml deleted file mode 100644 index 08d09cf..0000000 --- a/.github/workflows/linting.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- -name: Linting - -# yamllint disable-line rule:truthy -on: - push: - branches: - - main - - "renovate/**" - pull_request: - -jobs: - linting: - runs-on: ubuntu-latest - steps: - - name: Checkout source - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - - name: Cache pre-commit - uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4 - with: - path: ~/.cache/pre-commit - key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }} - - - name: Set up python - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5 - with: - python-version: "3.x" - - - name: Install dependencies - run: python -m pip install pre-commit - - - name: Run pre-commit - run: pre-commit run --all-files --color always --verbose diff --git a/.github/workflows/tags.yaml b/.github/workflows/tags.yaml new file mode 100644 index 0000000..d3a6bf8 --- /dev/null +++ b/.github/workflows/tags.yaml @@ -0,0 +1,51 @@ +--- +name: Bump Version Tag + +on: + push: + branches: + - main + paths: + - "**/*" + - "!**/*.json" + - "!**/*.json5" + - "!**/*.md" + - "!.github/**" + - "!.gitignore" + - "!.pre-commit-config.yaml" + workflow_dispatch: + +jobs: + tags: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout source + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 + with: + fetch-depth: 0 + + - name: Bump version and push tag + id: bump-version + # yamllint disable-line rule:line-length + uses: anothrNick/github-tag-action@afe4b67b57b8ab0908e4767109a5342003639e2e # v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + WITH_V: true + + - name: Extract major tag + id: extract-major + run: >- + echo major_tag=$(echo ${{ steps.bump-version.outputs.new_tag }} | cut + -d'.' -f1) >> $GITHUB_OUTPUT + + # this is done manually as need a non-annotated tag + # TODO: replace with https://github.com/actions/publish-action + - name: Update major tag + run: |- + git config user.name github-actions + git config user.email github-actions@github.com + git tag --force ${{ steps.extract-major.outputs.major_tag }} \ + ${{ steps.bump-version.outputs.new_tag }} + git push origin ${{ steps.extract-major.outputs.major_tag }} --force diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 27bda19..1be1752 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ --- repos: - repo: https://github.com/adrienverge/yamllint - rev: v1.33.0 + rev: v1.35.1 hooks: - id: yamllint args: @@ -9,22 +9,57 @@ repos: --config-data={ extends: default, rules: { + anchors: enable, + braces: { + forbid: non-empty + }, + brackets: { + forbid: non-empty + }, + colons: enable, + commas: enable, comments: { min-spaces-from-content: 1 + }, + comments-indentation: enable, + document-end: disable, + document-start: enable, + empty-lines: enable, + empty-values: disable, + float-values: enable, + hyphens: enable, + indentation: enable, + key-duplicates: enable, + key-ordering: disable, + line-length: enable, + new-line-at-end-of-file: enable, + new-lines: enable, + octal-values: enable, + quoted-strings: { + quote-type: double, + required: only-when-needed + }, + trailing-spaces: enable, + truthy: { + check-keys: false } } } - --strict - repo: https://github.com/crate-ci/typos - rev: v1.16.26 + rev: v1.22.9 hooks: - id: typos args: - --force-exclude + - --hidden + - --locale=en-gb - repo: https://github.com/igorshubovych/markdownlint-cli rev: v0.38.0 hooks: - id: markdownlint-fix + args: + - --dot - repo: https://github.com/Lucas-C/pre-commit-hooks rev: v1.5.4 hooks: @@ -33,8 +68,11 @@ repos: rev: v3.1.0 hooks: - id: prettier + args: + - --prose-wrap=always + - --quote-props=as-needed - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: check-added-large-files - id: check-case-conflict diff --git a/actions/README.md b/actions/README.md new file mode 100644 index 0000000..bf9b316 --- /dev/null +++ b/actions/README.md @@ -0,0 +1,5 @@ +# Composite Actions + +A set of +[composite actions](https://docs.github.com/en/actions/creating-actions/creating-a-composite-action) +that can be called by other workflows in the ARC organisation. diff --git a/actions/add-to-project/README.md b/actions/add-to-project/README.md new file mode 100644 index 0000000..15e20bb --- /dev/null +++ b/actions/add-to-project/README.md @@ -0,0 +1,55 @@ +# add-to-project + +This action can be used in the following manner to add issues to project boards: + +```yaml +jobs: + add-issue-to-project: + runs-on: ubuntu-latest + steps: + - uses: UCL-ARC/.github/actions/add-to-project@vx + with: + app-id: ${{ secrets.APP_ID }} + app-pem: ${{ secrets.APP_PEM }} + project-url: project_board_url +``` + +where `x` is the `major` version of the action, and `project_board_url` is the +full URL of the project board to which the repository's issues should be added. +If a particular label should trigger the action to go to a different project +board then one may specify the `label` input as follows: + +```yaml +jobs: + add-issue-to-project: + runs-on: ubuntu-latest + steps: + - uses: UCL-ARC/.github/actions/add-to-project@vx + with: + app-id: ${{ secrets.APP_ID }} + app-pem: ${{ secrets.APP_PEM }} + label: label_name + project-url: project_board_url +``` + +where `label_name` is a +[comma-separated list of labels](https://github.com/actions/add-to-project/tree/main?tab=readme-ov-file#inputs). +Lastly, `label-operator` may be used to specify the logical operator to be used +when checking for the presence of labels. The default value is `OR`, but may be +configured as follows: + +```yaml +jobs: + add-issue-to-project: + runs-on: ubuntu-latest + steps: + - uses: UCL-ARC/.github/actions/add-to-project@vx + with: + app-id: ${{ secrets.APP_ID }} + app-pem: ${{ secrets.APP_PEM }} + label: label_name + label-operator: AND + project-url: project_board_url +``` + +where `label-operator` may be set to `AND`, `NOT` or `OR`. diff --git a/actions/add-to-project/action.yml b/actions/add-to-project/action.yml new file mode 100644 index 0000000..1c780da --- /dev/null +++ b/actions/add-to-project/action.yml @@ -0,0 +1,44 @@ +--- +name: Add Issues to Project +description: Add issues to the GitHub project board + +inputs: + app-id: + description: Application ID + required: true + + app-pem: + description: Application private key + required: true + + labeled: + description: Label to filter issues by + default: "" + + label-operator: + description: Operator to filter issues by label + default: OR + + project-url: + description: URL of the project board to add issues to + required: true + +runs: + using: composite + steps: + - name: Generate token + id: generate-token + # yamllint disable-line rule:line-length + uses: actions/create-github-app-token@ad38cffc07bac6e3857755914c4c88bfd2db4da4 # v1 + with: + app-id: ${{ inputs.app-id }} + private-key: ${{ inputs.app-pem }} + + - name: Get project data + # yamllint disable-line rule:line-length + uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2 + with: + github-token: ${{ steps.generate-token.outputs.token }} + label-operator: ${{ inputs.label-operator }} + labeled: ${{ inputs.labeled }} + project-url: ${{ inputs.project-url }} diff --git a/actions/links/README.md b/actions/links/README.md new file mode 100644 index 0000000..33099d1 --- /dev/null +++ b/actions/links/README.md @@ -0,0 +1,30 @@ +# links + +This action can be used in the following manner: + +```yaml +jobs: + links: + runs-on: ubuntu-latest + timeout-minutes: 2 + steps: + - uses: UCL-ARC/.github/actions/links@vx + with: + github-token: ${{ secrets.GITHUB_TOKEN }} +``` + +where `x` is the `major` version of the action. If custom link checking is +required, one can add custom inputs through `lychee-args`, i.e.: + +```yaml +jobs: + linting: + runs-on: ubuntu-latest + steps: + - uses: UCL-ARC/.github/actions/linting@vx + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + lychee-args: + --base . --verbose --no-progress './**/*.md' './**/*.html' + './**/*.rst' +``` diff --git a/actions/links/action.yml b/actions/links/action.yml new file mode 100644 index 0000000..304145e --- /dev/null +++ b/actions/links/action.yml @@ -0,0 +1,29 @@ +--- +name: Links +description: Checks the links in a repo work + +inputs: + github-token: + description: GitHub token + required: true + + lychee-args: + description: + Arguments to pass to lychee + (https://github.com/lycheeverse/lychee#commandline-parameters) + default: + --base . --verbose --no-progress './**/*.md' './**/*.html' './**/*.rst' + +runs: + using: composite + steps: + - name: Checkout source + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 + + - name: Check links + # yamllint disable-line rule:line-length + uses: lycheeverse/lychee-action@2b973e86fc7b1f6b36a93795fe2c9c6ae1118621 # v1 + with: + args: ${{ inputs.lychee-args }} + failIfEmpty: false + token: ${{ inputs.github-token }} diff --git a/actions/linting/README.md b/actions/linting/README.md new file mode 100644 index 0000000..7d0067c --- /dev/null +++ b/actions/linting/README.md @@ -0,0 +1,15 @@ +# linting + +This action can be used in the following manner: + +```yaml +jobs: + linting: + runs-on: ubuntu-latest + steps: + - uses: UCL-ARC/.github/actions/linting@vx + with: + pre-commit-config: ./.pre-commit-config.yaml +``` + +where `x` is the `major` version of the action. diff --git a/actions/linting/action.yml b/actions/linting/action.yml new file mode 100644 index 0000000..71a9c2b --- /dev/null +++ b/actions/linting/action.yml @@ -0,0 +1,33 @@ +--- +name: Linting +description: Runs pre-commit over the repo + +inputs: + pre-commit-config: + description: The pre-commit config file of the current repo + required: true + +runs: + using: composite + steps: + - name: Checkout source + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 + + - name: Cache pre-commit + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4 + with: + path: ~/.cache/pre-commit + key: cache-${{ hashFiles(inputs.pre-commit-config) }} + + - name: Set up python + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5 + with: + python-version: 3.x + + - name: Install pre-commit + shell: bash + run: python -m pip install pre-commit + + - name: Run pre-commit + shell: bash + run: pre-commit run --all-files --color always --verbose diff --git a/renovate/README.md b/renovate/README.md index 4dd6f6c..47af88b 100644 --- a/renovate/README.md +++ b/renovate/README.md @@ -1,10 +1,9 @@ # Renovate To enable `Renovate` in a given repository, one must install and enable the -[GitHub application](https://github.com/apps/renovate). -One must then make a `.renovaterc.json5` file in the repository, of the following -form. -Note, the two `/` is intentional. +[GitHub application](https://github.com/apps/renovate). One must then make a +`.renovaterc.json5` file in the repository, of the following form. Note, the two +`/` is intentional. ```json5 { @@ -19,9 +18,9 @@ One can then view the logs here . To benefit from the automerging capabilities of the default config it is _highly_ recommended having `required` status checks that run on anything that -`Renovate` updates. -In `GitHub Actions` this can be performed with the following at the top of the -relevant workflows, which will run `Renovate` on pull requests or branches. +`Renovate` updates. In `GitHub Actions` this can be performed with the following +at the top of the relevant workflows, which will run `Renovate` on pull requests +or branches. ```yaml on: @@ -57,9 +56,8 @@ Alternatively, if you're using in your repo, you can modify and import the following two. The first one enables the `Restrict deletions`, `Block force pushes` settings, -as well as requiring a series of named status checks to pass. -No one is able to bypass these rules. -Make sure to add all status checks that you require. +as well as requiring a series of named status checks to pass. No one is able to +bypass these rules. Make sure to add all status checks that you require. ```json {