From 921df6a1d812b07bd4a83b100ec4fdb906008f6b Mon Sep 17 00:00:00 2001 From: DJ Adams Date: Tue, 24 Oct 2023 08:01:17 +0000 Subject: [PATCH] add workflows --- .github/workflows/community-id-requester.yaml | 92 +++++++++++++++++++ .../workflows/disallowed-content-checks.yaml | 72 +++++++++++++++ .github/workflows/markdown-checks.yaml | 60 ++++++++++++ .github/workflows/markdownlint/config.yaml | 9 ++ .github/workflows/markdownlint/md901.js | 23 +++++ .../markdownlint/problem-matcher.json | 17 ++++ .github/workflows/merged-pr-labeler.yaml | 58 ++++++++++++ 7 files changed, 331 insertions(+) create mode 100644 .github/workflows/community-id-requester.yaml create mode 100644 .github/workflows/disallowed-content-checks.yaml create mode 100644 .github/workflows/markdown-checks.yaml create mode 100644 .github/workflows/markdownlint/config.yaml create mode 100644 .github/workflows/markdownlint/md901.js create mode 100644 .github/workflows/markdownlint/problem-matcher.json create mode 100644 .github/workflows/merged-pr-labeler.yaml diff --git a/.github/workflows/community-id-requester.yaml b/.github/workflows/community-id-requester.yaml new file mode 100644 index 0000000..7c3d727 --- /dev/null +++ b/.github/workflows/community-id-requester.yaml @@ -0,0 +1,92 @@ +name: SAP Community profile URL requester + +# What the execution context is: +# The assignment of a label to an issue or pull request indicating +# that the contribution was valuable. + +# What it does: +# Adds a comment to the issue or pull request asking the author for +# their SAP Community profile URL ('community ID'). + +# Why we need it: +# So that we can properly recognize the contribution in SAP Community. + +# What's important to know: +# The label is specified at the start of the 'community-id-requester' +# job as an environment variable LABEL, and also in the job-level condition. +# Also, it adds a comment only after the first time the label is added, and +# only if there are no other issues / pull requests already labeled. + +on: + pull_request_target: + types: [labeled] + issues: + types: [labeled] + +jobs: + + community-id-requester: + + env: + LABEL: "contribution" + runs-on: ubuntu-20.04 + if: contains(github.repositoryUrl, 'github.com') && github.event.label.name == 'contribution' + + steps: + + - id: token_gen + name: Generate app installation token + uses: machine-learning-apps/actions-app-token@0.21 + with: + APP_PEM: ${{ secrets.SAP_CODOC_APP_PEM_BASE64 }} + APP_ID: ${{ secrets.SAP_CODOC_APP_ID }} + + - id: checkout + name: Check out the repo + uses: actions/checkout@v2 + with: + token: ${{ steps.token_gen.outputs.app_token }} + + - id: issue_details + name: Determine related details if issue + if: github.event_name == 'issues' + run: | + echo "OBJECTTYPE=issue" >> $GITHUB_ENV + echo "CONTRIBUTIONTYPE=feedback" >> $GITHUB_ENV + echo "OBJECTNR=${{ github.event.issue.number }}" >> $GITHUB_ENV + echo "CONTRIBUTOR=${{ github.event.issue.user.login }}" >> $GITHUB_ENV + + - id: pull_request_details + name: Determine related details if pull request + if: github.event_name == 'pull_request_target' + run: | + echo "OBJECTTYPE=pr" >> $GITHUB_ENV + echo "CONTRIBUTIONTYPE=content" >> $GITHUB_ENV + echo "OBJECTNR=${{ github.event.pull_request.number }}" >> $GITHUB_ENV + echo "CONTRIBUTOR=${{ github.event.pull_request.user.login }}" >> $GITHUB_ENV + + - id: auth_gh + name: Authenticate gh to repo + run: echo -n ${{ steps.token_gen.outputs.app_token }} | gh auth login --with-token + + - id: count_label_additions + name: Count number of times label has been added + run: | + endpoint="repos/${{ github.repository }}/issues/$OBJECTNR/events" + count=$(gh api --jq "[.[]|(select(.event==\"labeled\" and .label.name==\"$LABEL\"))] | length" $endpoint) + echo "LABELADDITIONCOUNT=$count" >> $GITHUB_ENV + + - id: count_previous_labeled_objects + name: Count how many other issues / pull requests are so labeled + run: | + querystring="is:${OBJECTTYPE}+label:${LABEL}+author:${CONTRIBUTOR}+repo:${GITHUB_REPOSITORY}" + result=$(gh api --jq '.items[] | [.number, .title] | @tsv' "/search/issues?q=$querystring") + echo "$result" + echo "OBJECTCOUNT=$(wc -l <<< $result)" | tee -a $GITHUB_ENV + + - id: requester + name: Ask for SAP Community profile URL if label added for first time and no prev labeled issue / pr + if: env.LABELADDITIONCOUNT == 1 && env.OBJECTCOUNT <= 1 + run: | + printf "Thank you for your valuable ${CONTRIBUTIONTYPE} contribution, @${CONTRIBUTOR}! So that we can [recognize your contribution in SAP Community](https://github.com/SAP-docs/contribution-guidelines/blob/main/docs/recognition.md), please tell us your SAP Community profile URL in a reply to this comment; don't include any other text, just the URL on its own, like this:\n\n\`\`\`\nhttps://people.sap.com/your-user-name\n\`\`\`\n\nThanks!" \ + | gh $OBJECTTYPE comment $OBJECTNR --body-file - diff --git a/.github/workflows/disallowed-content-checks.yaml b/.github/workflows/disallowed-content-checks.yaml new file mode 100644 index 0000000..04a2697 --- /dev/null +++ b/.github/workflows/disallowed-content-checks.yaml @@ -0,0 +1,72 @@ +name: Disallowed content checker + +# What the execution context is: +# A pull request on the main branch. Only relevant for users who +# don't have admin access on the repository. + +# What it does: +# Checks to see if there are any files included in the pull request +# that we cannot accept. Only files in the docs/ directory are open +# to contribution. + +# Why we need it: +# So the repository remains stable and we can focus on documentation +# contributions. + +# What's important to know: +# The filter used in the check_files_changed step is a negated one, +# i.e. notice the use of the '!'. Read the filter like this: "The +# disallowed files are any that DON'T match docs/**". + +on: + pull_request_target: + branches: [main] + +jobs: + main: + runs-on: ubuntu-20.04 + steps: + + - id: token_gen + name: Generate app installation token + uses: machine-learning-apps/actions-app-token@0.21 + with: + APP_PEM: ${{ secrets.SAP_CODOC_APP_PEM_BASE64 }} + APP_ID: ${{ secrets.SAP_CODOC_APP_ID }} + + - id: checkout + name: Check out the repo + uses: actions/checkout@v2 + with: + token: ${{ steps.token_gen.outputs.app_token }} + + - id: auth_gh + name: Authenticate gh to repo + run: echo -n ${{ steps.token_gen.outputs.app_token }} | gh auth login --with-token + + - id: determine_permission + name: Look up actor's repository permission level + run: | + permission="$(gh api --jq .permission "/repos/$GITHUB_REPOSITORY/collaborators/$GITHUB_ACTOR/permission")" + echo "repo_permission=$permission" >> $GITHUB_ENV + + - id: check_files_changed + name: Checks if disallowed content has been changed + if: env.repo_permission != 'admin' + uses: dorny/paths-filter@v2 + with: + list-files: 'shell' + filters: | + disallowed: + - '!docs/**' + + - id: comment_on_disallowed + if: steps.check_files_changed.outputs.disallowed == 'true' + env: + DOCS_LOC: "/${{ github.repository }}/tree/${{ github.base_ref }}/docs" + REVERT_COMMAND: '`git checkout origin/main `' + DISALLOWED_FILES: ${{ steps.check_files_changed.outputs.disallowed_files }} + run: | + printf "🚨 Hi there. It looks like you've included some files in this pull request that we can't accept in a contribution. Only actual documentation content, which is managed in the [docs]($DOCS_LOC) directory, is open for contribution.\n\nThe disallowed files that you submitted are:\n\n$DISALLOWED_FILES.\n\nYou'll need to revert all of the files you changed in that list using [GitHub Desktop](https://docs.github.com/en/free-pro-team@latest/desktop/contributing-and-collaborating-using-github-desktop/reverting-a-commit) or $REVERT_COMMAND. Once you get those files reverted, we can continue with the review process." \ + | gh pr comment ${{ github.event.pull_request.number }} --body-file - + exit 1 diff --git a/.github/workflows/markdown-checks.yaml b/.github/workflows/markdown-checks.yaml new file mode 100644 index 0000000..89fe01f --- /dev/null +++ b/.github/workflows/markdown-checks.yaml @@ -0,0 +1,60 @@ +name: Markdown linter + +# What the execution context is: +# The creation of a pull request. Can also be triggered manually. + +# What it does: +# Performs Markdown linting on the content of the pull request. + +# Why we need it: +# To maintain a level of consistency in the markup content. + +# What's important to know: +# As well as the rules defined in the configuration, a custom +# rule is also employed to check title case. + +on: + workflow_dispatch: + pull_request: + branches: [main] + paths: 'docs/**' + +jobs: + main: + if: contains(github.repositoryUrl, 'github.com') + runs-on: ubuntu-20.04 + steps: + + - id: checkout_repo + name: Check out the repository content + uses: actions/checkout@v2 + + - id: check_files_changed + uses: dorny/paths-filter@v2 + with: + list-files: 'escape' + filters: | + changed: + - 'docs/**' + + - id: add_matcher + name: Add the matcher for markdownlint style message output + run: "echo ::add-matcher::.github/workflows/markdownlint/problem-matcher.json" + + - id: install_linter + name: Install linting tool, custom rule and rule helpers + run: | + npm install \ + --no-package-lock \ + --no-save \ + markdownlint-cli@0.27 markdownlint-rule-titlecase markdownlint-rule-helpers@0.18 + + - id: run_linter + if: steps.check_files_changed.outputs.changed_files + name: Run linter with specific rules, on the docs/ content + run: | + npx markdownlint \ + --config .github/workflows/markdownlint/config.yaml \ + --rules .github/workflows/markdownlint/md901 \ + --rules markdownlint-rule-titlecase \ + ${{ steps.check_files_changed.outputs.changed_files }} diff --git a/.github/workflows/markdownlint/config.yaml b/.github/workflows/markdownlint/config.yaml new file mode 100644 index 0000000..559db92 --- /dev/null +++ b/.github/workflows/markdownlint/config.yaml @@ -0,0 +1,9 @@ +# All rules are inactive by default. +default: false + +# These specific rules are active. +# See https://github.com/DavidAnson/markdownlint#rules--aliases for details. +no-reversed-links: true +no-missing-space-atx: true +no-multiple-space-atx: true +heading-increment-no-blockquote: true diff --git a/.github/workflows/markdownlint/md901.js b/.github/workflows/markdownlint/md901.js new file mode 100644 index 0000000..533f03f --- /dev/null +++ b/.github/workflows/markdownlint/md901.js @@ -0,0 +1,23 @@ +// @ts-check + +"use strict"; + +const { addErrorDetailIf, filterTokens } = require("markdownlint-rule-helpers"); + +module.exports = { + "names": [ "MD901", "heading-increment-no-blockquote" ], + "description": "Custom version of MD001. Heading levels should only increment by one level at a time, except if in a blockquote", + "tags": [ "headings", "headers" ], + "function": function MD901(params, onError) { + let prevLevel = 0; + filterTokens(params, "heading_open", function forToken(token) { + const level = Number.parseInt(token.tag.slice(1), 10); + if (token.line.match(/^\s*> ?/)) return; + if (prevLevel && (level > prevLevel)) { + addErrorDetailIf(onError, token.lineNumber, + "h" + (prevLevel + 1), "h" + level); + } + prevLevel = level; + }); + } +}; diff --git a/.github/workflows/markdownlint/problem-matcher.json b/.github/workflows/markdownlint/problem-matcher.json new file mode 100644 index 0000000..3e68dfd --- /dev/null +++ b/.github/workflows/markdownlint/problem-matcher.json @@ -0,0 +1,17 @@ +{ + "problemMatcher": [ + { + "owner": "markdownlint", + "pattern": [ + { + "regexp": "([^:]*):(\\d+):?(\\d+)?\\s([\\w-\\/]*)\\s(.*)", + "file": 1, + "line": 2, + "column": 3, + "code": 4, + "message": 5 + } + ] + } + ] +} diff --git a/.github/workflows/merged-pr-labeler.yaml b/.github/workflows/merged-pr-labeler.yaml new file mode 100644 index 0000000..f855bbc --- /dev/null +++ b/.github/workflows/merged-pr-labeler.yaml @@ -0,0 +1,58 @@ +name: Merged pull request labeler + +# What the execution context is: +# The merging (not just closing) of a pull request. + +# What it does: +# Assigns the 'valuable contribution' label. + +# Why we need it: +# To mark a valuable pull request contribution, and thus to cause the +# SAP Community profile URL requester to be triggered. + +# What's important to know: +# The label to assign is defined at the start of the job, in the LABEL +# environment variable. The label is not assigned if the actor is an administrator. + +on: + pull_request_target: + types: [closed] + +jobs: + + assign-label-on-merge: + if: contains(github.repositoryUrl, 'github.com') && github.event.pull_request.merged + env: + LABEL: "contribution" + runs-on: ubuntu-20.04 + + steps: + + - id: token_gen + name: Generate app installation token + uses: machine-learning-apps/actions-app-token@0.21 + with: + APP_PEM: ${{ secrets.SAP_CODOC_APP_PEM_BASE64 }} + APP_ID: ${{ secrets.SAP_CODOC_APP_ID }} + + - id: checkout + name: Check out the repo + uses: actions/checkout@v2 + with: + token: ${{ steps.token_gen.outputs.app_token }} + + - id: auth_gh + name: Authenticate gh to repo + run: echo -n ${{ steps.token_gen.outputs.app_token }} | gh auth login --with-token + + - id: determine_permission + name: Look up repository permission level for PR author + run: | + pr_author="$(gh api --jq .user.login "${{ github.event.pull_request._links.self.href }}")" + permission="$(gh api --jq .permission "/repos/$GITHUB_REPOSITORY/collaborators/$pr_author/permission")" + echo "pr_author=$pr_author" + echo "repo_permission=$permission" | tee --append "$GITHUB_ENV" + + - id: assign_label + if: env.repo_permission != 'admin' + run: gh pr edit ${{ github.event.number }} --add-label "$LABEL"