Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: Build and Test

on:
push:
pull_request:
workflow_dispatch:

jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: ./build_and_test
19 changes: 19 additions & 0 deletions .github/workflows/format_and_update_mdsnippets.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Format and Update MDSnippets
on:
push:
jobs:
format_and_snippets:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run format_and_update_mdsnippets
run: ./format_and_update_mdsnippets
- name: Git Commit and Push
uses: github-actions-x/[email protected]
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
commit-message: ". d format and update mdsnippets"
rebase: 'true'
push-branch: 'main'
name: GitHub Actions [bot]
email: [email protected]
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__pycache__/
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,16 @@ Changes that don't impact the code, but do change documentation around the code.

The basic intention annotations are comprehensive to describe any kind of change, but it may be useful to extend the notation to your project to provide additional detail that is useful in your context. Read more about [Extension Intensions](Extension%20Intentions.md).

# Compliance validation

You can validate that a commit message is valid, for example in a Git pre-commit hook, a GitHub Action, or GitLab's [Validate Commit Messages](https://docs.gitlab.com/user/project/repository/push_rules/#validate-commit-messages) by using the following regex:

<!-- snippet: compliance_regex.txt -->
```txt
^[.!^@] [a-zA-Z@]( .*)?$
```
<!-- endSnippet -->

# Provable Refactorings
[2]:#provable-refactorings

Expand Down
4 changes: 4 additions & 0 deletions build_and_test
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -euo pipefail

python3 -m unittest -v
8 changes: 8 additions & 0 deletions format_and_update_mdsnippets
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail

dotnet tool install --global MarkdownSnippets.Tool
mdsnippets .

python3 -m pip install black
black .
5 changes: 5 additions & 0 deletions mdsnippets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"Convention": "InPlaceOverwrite",
"WriteHeader": false,
"OmitSnippetLinks": true
}
Empty file added tools/__init__.py
Empty file.
1 change: 1 addition & 0 deletions tools/compliance_regex.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
^[.!^@] [a-zA-Z@]( .*)?$
43 changes: 43 additions & 0 deletions tools/test__compliance_regex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import unittest

import re
from pathlib import Path

SCRIPT_DIR = Path(__file__).parent

COMPLIANCE_REGEX = re.compile((SCRIPT_DIR / "compliance_regex.txt").read_text().strip())

MATCHING = [
". r rename variable",
"^ r rename variable",
"! r rename variable",
"@ r clean up a bunch of stuff",
"! F Add about page",
"! B Fix crash on startup",
". a Format with prettier",
". n No-op commit",
". t Add missing tests",
"@ @ Checkpoint: work in progress",
". e capture artifacts in CI",
]

NONMATCHING_EXAMPLES = [
"r rename variable",
". rename variable",
".r rename variable",
"! B Fix crash on startup",
". rt rename variable in test",
"- r rename variable",
"Merge branch 'startup-crash'",
"WIP: diagnosing crash on startup",
]


class Tess(unittest.TestCase):
def test__matching(self):
for example in MATCHING:
self.assertTrue(COMPLIANCE_REGEX.match(example))

def test__nonmatching(self):
for example in NONMATCHING_EXAMPLES:
self.assertFalse(COMPLIANCE_REGEX.match(example))