github-rest-api 0.52.0__tar.gz → 0.53.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/.github/workflows/merge-pr.yaml +9 -7
  2. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/PKG-INFO +1 -1
  3. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/scripts/lint_repo.py +14 -3
  4. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/pyproject.toml +1 -1
  5. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/tests/test_lint_repo.py +29 -5
  6. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/uv.lock +1 -1
  7. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/.devcontainer/devcontainer.json +0 -0
  8. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/.github/workflows/check-workflow-template.yaml +0 -0
  9. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/.github/workflows/claude.yaml +0 -0
  10. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/.github/workflows/create-pr-dev-to-main.yaml +0 -0
  11. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/.github/workflows/create-pr-to-dev.yaml +0 -0
  12. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/.github/workflows/create-pr-to-main.yaml +0 -0
  13. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/.github/workflows/pr-workflow.yaml +0 -0
  14. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/.github/workflows/release.yaml +0 -0
  15. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/.github/workflows/remove-branch.yaml +0 -0
  16. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/.gitignore +0 -0
  17. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/AGENTS.md +0 -0
  18. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/CLAUDE.md +0 -0
  19. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/README.md +0 -0
  20. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/__init__.py +0 -0
  21. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/github.py +0 -0
  22. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/pr_content.py +0 -0
  23. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/scripts/__init__.py +0 -0
  24. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/scripts/cargo/__init__.py +0 -0
  25. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/scripts/cargo/benchmark.py +0 -0
  26. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/scripts/cargo/profiling.py +0 -0
  27. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/scripts/cargo/utils.py +0 -0
  28. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/scripts/container/__init__.py +0 -0
  29. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/scripts/container/build_container_images.py +0 -0
  30. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/scripts/container/config_container.py +0 -0
  31. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/scripts/container/update_version_containerfile.py +0 -0
  32. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/scripts/github/__init__.py +0 -0
  33. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/scripts/github/auto_merge_pull_request.py +0 -0
  34. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/scripts/github/create_github_repo.py +0 -0
  35. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/scripts/github/create_pull_request.py +0 -0
  36. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/scripts/github/release_on_github.py +0 -0
  37. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/scripts/github/remove_branch.py +0 -0
  38. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/scripts/github/upload_image_to_issue.py +0 -0
  39. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/scripts/utils.py +0 -0
  40. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/github_rest_api/utils.py +0 -0
  41. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/memory/MEMORY.md +0 -0
  42. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/memory/feedback_test_runner.md +0 -0
  43. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/tests/__init__.py +0 -0
  44. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/tests/test_auto_merge_pull_request.py +0 -0
  45. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/tests/test_build_container_images.py +0 -0
  46. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/tests/test_create_github_repo.py +0 -0
  47. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/tests/test_create_pull_request.py +0 -0
  48. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/tests/test_github.py +0 -0
  49. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/tests/test_pr_content.py +0 -0
  50. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/tests/test_release_on_github.py +0 -0
  51. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/tests/test_upload_image_to_issue.py +0 -0
  52. {github_rest_api-0.52.0 → github_rest_api-0.53.1}/tests/test_utils.py +0 -0
@@ -42,13 +42,6 @@ on:
42
42
  permissions:
43
43
  contents: write
44
44
  pull-requests: write
45
- concurrency:
46
- # Every run rescans all open PRs, so overlapping runs are pure duplicate work
47
- # and the newest run always sees the freshest state. Do not cancel in
48
- # progress: a run cancelled midway through the merge API call is worse than a
49
- # redundant one.
50
- group: merge-pull-request
51
- cancel-in-progress: false
52
45
  jobs:
53
46
  merge_pull_request:
54
47
  # A triggering workflow that failed, was cancelled or was skipped left the
@@ -58,6 +51,15 @@ jobs:
58
51
  if: |
59
52
  github.event_name != 'workflow_run'
60
53
  || github.event.workflow_run.conclusion == 'success'
54
+ concurrency:
55
+ # Every run rescans all open PRs, so overlapping runs are pure duplicate
56
+ # work and the newest run always sees the freshest state. Do not cancel
57
+ # in progress: a run cancelled midway through the merge API call is worse
58
+ # than a redundant one. This is set on the job rather than the workflow
59
+ # so that a run whose `if` skips the job never joins the group, where it
60
+ # would replace (cancel) another PR's pending merge run.
61
+ group: merge-pull-request
62
+ cancel-in-progress: false
61
63
  uses: legendu-net/.github/.github/workflows/merge-pr.yaml@main
62
64
  with:
63
65
  dry_run: ${{ inputs.dry_run || false }}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: github-rest-api
3
- Version: 0.52.0
3
+ Version: 0.53.1
4
4
  Summary: Simple wrapper of GitHub REST APIs.
5
5
  Author-email: Ben Du <longendu@yahoo.com>
6
6
  Classifier: Programming Language :: Python :: 3 :: Only
@@ -22,6 +22,7 @@ import argparse
22
22
  import os
23
23
  import re
24
24
  import shutil
25
+ import stat
25
26
  import subprocess as sp
26
27
  import sys
27
28
  from collections.abc import Callable, Sequence
@@ -29,6 +30,7 @@ from dataclasses import dataclass, field
29
30
  from pathlib import Path
30
31
  from typing import Literal, cast
31
32
 
33
+ from dulwich.index import IndexEntry
32
34
  from dulwich.repo import Repo
33
35
 
34
36
  #: The outcome of running one check.
@@ -44,6 +46,12 @@ LANGUAGES = ["python", "rust", "golang", "bash", "fish", "lua", "markdown"]
44
46
  def list_tracked_files(root: Path) -> list[str]:
45
47
  """List all git-tracked files in a repository.
46
48
 
49
+ Symbolic links are excluded: a link's content is linted through its
50
+ target (when tracked), and linting the link too would run every check
51
+ twice on the same content -- or, worse, with conflicting options (e.g. a
52
+ `CLAUDE.md` -> `AGENTS.md` link would get a different mdformat flavor than
53
+ its target).
54
+
47
55
  :param root: The root directory of the git repository (not an arbitrary
48
56
  subdirectory of one -- the returned paths, and every command a check
49
57
  later runs, are relative to this exact directory).
@@ -54,7 +62,10 @@ def list_tracked_files(root: Path) -> list[str]:
54
62
  # `surrogateescape` so a non-UTF-8 filename (which git tracks fine)
55
63
  # doesn't crash the whole run; it just won't print legibly.
56
64
  return sorted(
57
- name.decode(errors="surrogateescape") for name in repo.open_index()
65
+ name.decode(errors="surrogateescape")
66
+ for name, entry in repo.open_index().items()
67
+ # A conflicted entry (mid-merge) has no single mode; keep it.
68
+ if not (isinstance(entry, IndexEntry) and stat.S_ISLNK(entry.mode))
58
69
  )
59
70
  finally:
60
71
  repo.close()
@@ -363,7 +374,7 @@ def build_markdown_checks(files: Sequence[str], fix: bool = False) -> list[Check
363
374
  md_files = _files_matching(files, "*.md")
364
375
  if not md_files:
365
376
  return []
366
- skill_files = [f for f in md_files if Path(f).name == "SKILL.md"]
377
+ skill_files = [f for f in md_files if Path(f).name in ("SKILL.md", "AGENTS.md")]
367
378
  other_files = [f for f in md_files if f not in skill_files]
368
379
  checks = []
369
380
  if other_files:
@@ -380,7 +391,7 @@ def build_markdown_checks(files: Sequence[str], fix: bool = False) -> list[Check
380
391
  if skill_files:
381
392
  checks.append(
382
393
  Check(
383
- "markdown: mdformat (SKILL.md)",
394
+ "markdown: mdformat (SKILL.md/AGENTS.md)",
384
395
  command=_cmd(
385
396
  fix,
386
397
  ["mdformat", "--number", *skill_files],
@@ -4,7 +4,7 @@ requires = [ "hatchling" ]
4
4
 
5
5
  [project]
6
6
  name = "github-rest-api"
7
- version = "0.52.0"
7
+ version = "0.53.1"
8
8
  description = "Simple wrapper of GitHub REST APIs."
9
9
  readme = "README.md"
10
10
  authors = [ { name = "Ben Du", email = "longendu@yahoo.com" } ]
@@ -58,6 +58,16 @@ def test_list_tracked_files_ignores_untracked_files(tmp_path):
58
58
  assert list_tracked_files(tmp_path) == ["tracked.py"]
59
59
 
60
60
 
61
+ def test_list_tracked_files_excludes_symlinks(tmp_path):
62
+ _init_repo(tmp_path, {"AGENTS.md": "# Agents\n"})
63
+ (tmp_path / "CLAUDE.md").symlink_to("AGENTS.md")
64
+ porcelain.add(str(tmp_path), paths=["CLAUDE.md"])
65
+ # The link is tracked by git, but only its target should be linted.
66
+ with Repo(str(tmp_path)) as repo:
67
+ assert b"CLAUDE.md" in repo.open_index()
68
+ assert list_tracked_files(tmp_path) == ["AGENTS.md"]
69
+
70
+
61
71
  def test_list_tracked_files_survives_a_non_utf8_filename(tmp_path):
62
72
  # Git tracks arbitrary byte sequences as filenames; decoding with
63
73
  # `surrogateescape` must not raise on one that isn't valid UTF-8. Written
@@ -174,18 +184,21 @@ def test_build_rust_scripts_checks_includes_all_files():
174
184
  def test_build_markdown_checks_splits_skill_md(tmp_path):
175
185
  (tmp_path / "docs").mkdir()
176
186
  (tmp_path / "docs" / "SKILL.md").write_text("")
187
+ (tmp_path / "AGENTS.md").write_text("")
177
188
  (tmp_path / "README.md").write_text("")
178
- checks = build_markdown_checks(["README.md", "docs/SKILL.md"])
189
+ checks = build_markdown_checks(["README.md", "AGENTS.md", "docs/SKILL.md"])
179
190
  by_name = {c.name: c for c in checks}
180
191
  assert by_name["markdown: mdformat"].command == ["mdformat", "--check", "README.md"]
181
- assert by_name["markdown: mdformat (SKILL.md)"].command == [
192
+ assert by_name["markdown: mdformat (SKILL.md/AGENTS.md)"].command == [
182
193
  "mdformat",
183
194
  "--check",
184
195
  "--number",
196
+ "AGENTS.md",
185
197
  "docs/SKILL.md",
186
198
  ]
187
199
  assert by_name["markdown: codespell"].command == [
188
200
  "codespell",
201
+ "AGENTS.md",
189
202
  "README.md",
190
203
  "docs/SKILL.md",
191
204
  ]
@@ -531,24 +544,35 @@ def test_build_lua_checks_fix_mode():
531
544
  def test_build_markdown_checks_fix_mode(tmp_path):
532
545
  (tmp_path / "docs").mkdir()
533
546
  (tmp_path / "docs" / "SKILL.md").write_text("")
547
+ (tmp_path / "AGENTS.md").write_text("")
534
548
  (tmp_path / "README.md").write_text("")
535
- checks = build_markdown_checks(["README.md", "docs/SKILL.md"], fix=True)
549
+ checks = build_markdown_checks(
550
+ ["README.md", "AGENTS.md", "docs/SKILL.md"], fix=True
551
+ )
536
552
  by_name = {c.name: c.command for c in checks}
537
553
  assert by_name["markdown: mdformat"] == ["mdformat", "README.md"]
538
- assert by_name["markdown: mdformat (SKILL.md)"] == [
554
+ assert by_name["markdown: mdformat (SKILL.md/AGENTS.md)"] == [
539
555
  "mdformat",
540
556
  "--number",
557
+ "AGENTS.md",
541
558
  "docs/SKILL.md",
542
559
  ]
543
560
  assert by_name["markdown: codespell"] == [
544
561
  "codespell",
545
562
  "-w",
563
+ "AGENTS.md",
546
564
  "README.md",
547
565
  "docs/SKILL.md",
548
566
  ]
549
567
  # lychee has no autofix and stays non-fatal: unchanged.
550
568
  lychee = next(c for c in checks if c.name == "markdown: lychee")
551
- assert lychee.command == ["lychee", "--no-progress", "README.md", "docs/SKILL.md"]
569
+ assert lychee.command == [
570
+ "lychee",
571
+ "--no-progress",
572
+ "AGENTS.md",
573
+ "README.md",
574
+ "docs/SKILL.md",
575
+ ]
552
576
  assert lychee.fatal is False
553
577
 
554
578
 
@@ -542,7 +542,7 @@ wheels = [
542
542
 
543
543
  [[package]]
544
544
  name = "github-rest-api"
545
- version = "0.52.0"
545
+ version = "0.53.1"
546
546
  source = { editable = "." }
547
547
  dependencies = [
548
548
  { name = "dulwich" },