Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Annotate Specification Links in GH Actions #746

Merged
merged 40 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
40bcb8b
Corrected replaced unevaluated with additoinalProperties
suprith-hub Apr 17, 2024
4eac02c
First workflow
suprith-hub Apr 23, 2024
810d148
First workflow2
suprith-hub Apr 23, 2024
eecc7b7
Merge branch 'main' of https://github.com/Era-cell/JSON-Schema-Test-S…
suprith-hub Apr 23, 2024
3558c2c
Fake add to tests
suprith-hub Apr 23, 2024
ce52852
Python file location changed
suprith-hub Apr 23, 2024
79dc92f
TOKEN
suprith-hub Apr 23, 2024
cbdd175
change day2
suprith-hub Apr 24, 2024
c6b937c
Reading all jsons and spec urls added
suprith-hub Apr 24, 2024
df3bdec
path corrected
suprith-hub Apr 24, 2024
582e12b
logging logs check
suprith-hub Apr 24, 2024
f29d090
Wrong location sepcification
suprith-hub Apr 24, 2024
540a269
Log2
suprith-hub Apr 24, 2024
eb8fd76
Branch name specified
suprith-hub Apr 24, 2024
77527b6
Stupidity corrected
suprith-hub Apr 24, 2024
5f050a0
Final correction1
suprith-hub Apr 24, 2024
96f7683
Final correction2 - file names beautufied
suprith-hub Apr 24, 2024
1c17519
regex correction
suprith-hub Apr 24, 2024
891d026
First workflow2
suprith-hub Apr 23, 2024
7b84fb4
Merge branch 'main' of https://github.com/Era-cell/JSON-Schema-Test-S…
suprith-hub Apr 24, 2024
564e695
Walking through all leaf files
suprith-hub Apr 30, 2024
7b40efe
Base path for neighbouring file?
suprith-hub Apr 30, 2024
e88a2da
Works for all OS
suprith-hub Apr 30, 2024
2b1ffb7
Best practices followed with optimized code
suprith-hub Apr 30, 2024
0b780b2
Corected yaml format
suprith-hub Apr 30, 2024
2367412
Cases for rfc and iso written separately
suprith-hub Apr 30, 2024
3a50900
Clear existin annotations on same PR
suprith-hub Apr 30, 2024
f276661
template library, url loads changes
suprith-hub May 8, 2024
11f8e51
Added installing command in workflow
suprith-hub May 8, 2024
57c7c86
changed install location
suprith-hub May 8, 2024
d8ade40
inside run
suprith-hub May 8, 2024
e4bd755
dumbness2 corrected
suprith-hub May 8, 2024
4ebbeaf
Merge branch 'Era-cell/main'
Julian May 9, 2024
38628b7
Make the spec URLs structure a bit easier for internal use.
Julian May 9, 2024
8164577
Tidy up the specification annotator a bit.
Julian May 9, 2024
0810515
Markdown is apparently not (yet?) supported in annotations.
Julian May 9, 2024
1b719a8
Pick the line after the description when attaching spec annotations.
Julian May 9, 2024
d9ce71a
May as well also show quotes in the annotation.
Julian May 9, 2024
2dc1067
Move the workflow step title.
Julian May 9, 2024
4aec22c
Revert the changes to additionalProperties.json.
Julian May 9, 2024
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
21 changes: 21 additions & 0 deletions .github/workflows/show_specification_annotations.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Show Specification Annotations

on:
pull_request:
paths:
- 'tests/**'

jobs:
annotate:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'

- name: Generate Annotations
run: pip install uritemplate && bin/annotate-specification-links
115 changes: 115 additions & 0 deletions bin/annotate-specification-links
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#!/usr/bin/env python3
"""
Annotate pull requests to the GitHub repository with links to specifications.
"""

from __future__ import annotations

from pathlib import Path
from typing import Any
import json
import re
import sys

from uritemplate import URITemplate


BIN_DIR = Path(__file__).parent
TESTS = BIN_DIR.parent / "tests"
URLS = json.loads(BIN_DIR.joinpath("specification_urls.json").read_text())


def urls(version: str) -> dict[str, URITemplate]:
"""
Retrieve the version-specific URLs for specifications.
"""
for_version = {**URLS["json-schema"][version], **URLS["external"]}
return {k: URITemplate(v) for k, v in for_version.items()}


def annotation(
path: Path,
message: str,
line: int = 1,
level: str = "notice",
**kwargs: Any,
) -> str:
"""
Format a GitHub annotation.

See https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions
for full syntax.
"""

if kwargs:
additional = "," + ",".join(f"{k}={v}" for k, v in kwargs.items())
else:
additional = ""

relative = path.relative_to(TESTS.parent)
return f"::{level} file={relative},line={line}{additional}::{message}\n"


def line_number_of(path: Path, case: dict[str, Any]) -> int:
"""
Crudely find the line number of a test case.
"""
with path.open() as file:
description = case["description"]
return next(
(i + 1 for i, line in enumerate(file, 1) if description in line),
1,
)


def main():
# Clear annotations which may have been emitted by a previous run.
sys.stdout.write("::remove-matcher owner=me::\n")

for version in TESTS.iterdir():
if version.name in {"draft-next", "latest"}:
continue

version_urls = urls(version.name)

for path in version.rglob("*.json"):
try:
contents = json.loads(path.read_text())
except json.JSONDecodeError as error:
error = annotation(
level="error",
path=path,
line=error.lineno,
col=error.pos + 1,
title=str(error),
)
sys.stdout.write(error)

for test_case in contents:
specifications = test_case.get("specification")
if specifications is not None:
for each in specifications:
quote = each.pop("quote", "")
(kind, section), = each.items()

number = re.search(r"\d+", kind)
spec = "" if number is None else number.group(0)

url = version_urls[kind].expand(
spec=spec,
section=section,
)

message = f"{url}\n\n{quote}" if quote else url
sys.stdout.write(
annotation(
path=path,
line=line_number_of(path, test_case),
title="Specification Link",
message=message,
),
)


if __name__ == "__main__":
main()
34 changes: 34 additions & 0 deletions bin/specification_urls.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"json-schema": {
"draft2020-12": {
"core": "https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-01#section-{section}",
"validation": "https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-01#section-{section}"
},
"draft2019-09": {
"core": "https://json-schema.org/draft/2019-09/draft-handrews-json-schema-02#rfc.section.{section}",
"validation": "https://json-schema.org/draft/2019-09/draft-handrews-json-schema-validation-02#rfc.section.{section}"
},
"draft7": {
"core": "https://json-schema.org/draft-07/draft-handrews-json-schema-01#rfc.section.{section}",
"validation": "https://json-schema.org/draft-07/draft-handrews-json-schema-validation-01#rfc.section.{section}"
},
"draft6": {
"core": "https://json-schema.org/draft-06/draft-wright-json-schema-01#rfc.section.{section}",
"validation": "https://json-schema.org/draft-06/draft-wright-json-schema-validation-01#rfc.section.{section}"
},
"draft4": {
"core": "https://json-schema.org/draft-04/draft-zyp-json-schema-04#rfc.section.{section}",
"validation": "https://json-schema.org/draft-04/draft-fge-json-schema-validation-00#rfc.section.{section}"
},
"draft3": {
"core": "https://json-schema.org/draft-03/draft-zyp-json-schema-03.pdf"
}
},

"external": {
"ecma262": "https://262.ecma-international.org/{section}",
"perl5": "https://perldoc.perl.org/perlre#{section}",
"rfc": "https://www.rfc-editor.org/rfc/{spec}.txt#{section}",
"iso": "https://www.iso.org/obp/ui"
}
}
Loading