diff --git a/.github/verify_changelog.py b/.github/verify_changelog.py new file mode 100644 index 000000000000..93f399a97c6a --- /dev/null +++ b/.github/verify_changelog.py @@ -0,0 +1,78 @@ +import os, re +from enum import Enum +from github import Github + +# Format - Key: Array[Label, [StringsToIgnore]] +changelogToPrefix = { + 'fix': ["Fix", ["fixed a few things"]], + 'qol': ["Quality of Life", ["made something easier to use"]], + 'add': ["Feature", ["Added new mechanics or gameplay changes", "Added more things"]], + 'del': ["Removal", ["Removed old things"]], + 'spellcheck': ["Grammar and Formatting", ["fixed a few typos"]], + 'balance': ["Balance", ["rebalanced something"]], + 'code': ["Code Improvement", ["changed some code"]], + 'refactor': ["Refactor", ["refactored some code"]], + 'config': ["Config", ["changed some config setting"]], + 'admin': ["Admin", ["messed with admin stuff"]], + 'server': ["Server", ["something server ops should know"]], + 'soundadd': ["Sound", ["added a new sound thingy"]], + 'sounddel': ["Sound", ["removed an old sound thingy"]], + 'imageadd': ["Sprites", ["added some icons and images"]], + 'imagedel': ["Sprites", ["deleted some icons and images"]], + 'mapadd': ["Mapping", ["added a new map or section to a map"]], + 'maptweak': ["Mapping", ["tweaked a map"]], + 'ui' : ["UI", ["changed something relating to user interfaces"]] +} + +class Result(Enum): + INVALID = -1 + VALID = 0 + MISSING = 1 + +def validate_changelog(pr): + changelog_match = re.search(r"🆑(.*)/🆑", pr.body, re.S | re.M) + if changelog_match is None: + changelog_match = re.search(r":cl:(.*)/:cl:", pr.body, re.S | re.M) + if changelog_match is None: + return Result.MISSING + + lines = changelog_match.group(2).split('\n') + for line in lines: + line = line.strip() + if not line: + continue + + contentSplit = line.split(":") + + key = contentSplit.pop(0).strip() + content = ":".join(contentSplit).strip() + + if not key in changelogToPrefix: # some key that we didn't expect + print("Invalid changelog entry: " + line) + return Result.INVALID + + if content in changelogToPrefix[key][1]: # They left the template entry in + print("Invalid changelog entry: " + line) + return Result.INVALID + + return Result.VALID + +def main(): + g = Github(os.environ["TOKEN"]) + repo = g.get_repo(os.environ['REPO']) + + pr = repo.get_pull(int(os.environ["PR_NUMBER"])) + if not pr: + print("Not a PR.") + return Result.INVALID + + result = validate_changelog(pr) + + if result == Result.MISSING: + print("No changelog detected.") + + return result + + +if __name__ == '__main__': + main() diff --git a/.github/workflows/verify_changelog.yml b/.github/workflows/verify_changelog.yml new file mode 100644 index 000000000000..f53acf7dbf26 --- /dev/null +++ b/.github/workflows/verify_changelog.yml @@ -0,0 +1,49 @@ +name: Changelog Verification +on: + pull_request_target: + types: [edited] +jobs: + verify: + runs-on: ubuntu-latest + steps: + - name: "Check for ACTION_ENABLER secret and pass true to output if it exists to be checked by later steps" + id: value_holder + env: + ENABLER_SECRET: ${{ secrets.ACTION_ENABLER }} + run: | + unset SECRET_EXISTS + if [ -n "$ENABLER_SECRET" ]; then SECRET_EXISTS=true ; fi + echo "::set-output name=ACTIONS_ENABLED::$SECRET_EXISTS" + - name: Get The Script + if: steps.value_holder.outputs.ACTIONS_ENABLED + run: | + wget "https://raw.githubusercontent.com/${{ github.repository }}/master/.github/verify_changelog.py" + - name: Set up Python + if: steps.value_holder.outputs.ACTIONS_ENABLED + uses: actions/setup-python@v3 + with: + python-version: 3.8 + - name: Install dependencies + if: steps.value_holder.outputs.ACTIONS_ENABLED + run: | + python -m pip install --upgrade pip + python -m pip install pygithub + sudo apt-get install dos2unix + - name: Verify Changelog + id: verify_holder + if: steps.value_holder.outputs.ACTIONS_ENABLED + run: | + output=$(python verify_changelog.py) + echo "::set-output name=VERIFY_RESULT::$output" + env: + REPO: ${{ github.repository }} + TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_NUMBER: ${{ github.event.number }} + - name: Note Missing Changelog + if: steps.value_holder.outputs.ACTIONS_ENABLED && steps.verify_holder.outputs.VERIFY_RESULT == 1 + run: | + echo "::notice ::No changelog detected" + - name: Note Invalid Changelog + if: steps.value_holder.outputs.ACTIONS_ENABLED && steps.verify_holder.outputs.VERIFY_RESULT == -1 + run: | + echo "::error ::Changelog is invalid"