hackerrank-cli 2026.10.7__tar.gz → 2026.10.30__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 (78) hide show
  1. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/.github/dependabot.yml +2 -0
  2. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/.github/workflows/autofix.yml +3 -4
  3. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/.github/workflows/binaries.yml +12 -4
  4. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/.github/workflows/ci.yml +9 -5
  5. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/.github/workflows/docs.yml +2 -2
  6. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/.github/workflows/lint.yml +2 -2
  7. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/.github/workflows/publish-site.yml +2 -2
  8. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/.github/workflows/release.yml +12 -6
  9. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/Dockerfile +1 -1
  10. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/MANIFEST.in +2 -2
  11. {hackerrank_cli-2026.10.7/src/hackerrank_cli.egg-info → hackerrank_cli-2026.10.30}/PKG-INFO +18 -2
  12. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/README.rst +15 -0
  13. hackerrank_cli-2026.10.30/VERSION +1 -0
  14. hackerrank_cli-2026.10.30/docs/source/changelog/2026.10.1.1.md +7 -0
  15. hackerrank_cli-2026.10.30/docs/source/changelog/2026.10.30.md +14 -0
  16. hackerrank_cli-2026.10.30/docs/source/changelog/2026.10.7.md +7 -0
  17. hackerrank_cli-2026.10.30/docs/source/changelog/2026.10.8.md +6 -0
  18. hackerrank_cli-2026.10.30/docs/source/changelog.md +11 -0
  19. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/docs/source/conf.py +1 -1
  20. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/docs/source/development.rst +17 -8
  21. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/prek.toml +2 -2
  22. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/pyproject.toml +24 -20
  23. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/src/hackerrank_cli/__init__.py +123 -1
  24. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/src/hackerrank_cli/_version.py +3 -3
  25. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30/src/hackerrank_cli.egg-info}/PKG-INFO +18 -2
  26. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/src/hackerrank_cli.egg-info/SOURCES.txt +10 -5
  27. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/src/hackerrank_cli.egg-info/requires.txt +1 -1
  28. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/src/hackerrank_cli.egg-info/scm_file_list.json +9 -4
  29. hackerrank_cli-2026.10.30/src/hackerrank_cli.egg-info/scm_version.json +8 -0
  30. hackerrank_cli-2026.10.30/tests/test_help/test_help_questions_.txt +11 -0
  31. hackerrank_cli-2026.10.30/tests/test_help/test_help_questions_set_system_prompt_.txt +9 -0
  32. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/tests/test_help/test_help_root_.txt +1 -1
  33. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/tests/test_help.py +2 -1
  34. hackerrank_cli-2026.10.30/tests/test_system_prompt.py +266 -0
  35. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/uv.lock +646 -523
  36. hackerrank_cli-2026.10.7/CHANGELOG.rst +0 -27
  37. hackerrank_cli-2026.10.7/VERSION +0 -1
  38. hackerrank_cli-2026.10.7/docs/source/changelog.rst +0 -1
  39. hackerrank_cli-2026.10.7/src/hackerrank_cli.egg-info/scm_version.json +0 -8
  40. hackerrank_cli-2026.10.7/tests/test_help/test_help_questions_.txt +0 -10
  41. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/.dockerignore +0 -0
  42. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/.gitattributes +0 -0
  43. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/.github/workflows/dependabot-merge.yml +0 -0
  44. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/.github/workflows/nix.yml +0 -0
  45. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/.gitignore +0 -0
  46. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/.vale.ini +0 -0
  47. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/LICENSE +0 -0
  48. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/bin/__init__.py +0 -0
  49. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/bin/hackerrank_wrapper.py +0 -0
  50. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/docs/__init__.py +0 -0
  51. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/docs/source/__init__.py +0 -0
  52. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/docs/source/cli.rst +0 -0
  53. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/docs/source/index.rst +0 -0
  54. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/docs/source/macos-releases.rst +0 -0
  55. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/docs/source/migration.rst +0 -0
  56. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/docs/source/usage.rst +0 -0
  57. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/flake.lock +0 -0
  58. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/flake.nix +0 -0
  59. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/newsfragments/.gitkeep +0 -0
  60. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/setup.cfg +0 -0
  61. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/spelling_private_dict.txt +0 -0
  62. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/src/hackerrank_cli/__main__.py +0 -0
  63. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/src/hackerrank_cli/_sources.py +0 -0
  64. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/src/hackerrank_cli/py.typed +0 -0
  65. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/src/hackerrank_cli.egg-info/dependency_links.txt +0 -0
  66. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/src/hackerrank_cli.egg-info/entry_points.txt +0 -0
  67. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/src/hackerrank_cli.egg-info/not-zip-safe +0 -0
  68. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/src/hackerrank_cli.egg-info/top_level.txt +0 -0
  69. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/styles/snapper/LongProseLine.yml +0 -0
  70. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/styles/snapper/SemanticLineBreaks.yml +0 -0
  71. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/tests/__init__.py +0 -0
  72. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/tests/test_archive.py +0 -0
  73. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/tests/test_cli.py +0 -0
  74. /hackerrank_cli-2026.10.7/tests/test_help/test_help_archive_.txt → /hackerrank_cli-2026.10.30/tests/test_help/test_help_questions_archive_.txt +0 -0
  75. /hackerrank_cli-2026.10.7/tests/test_help/test_help_upload_.txt → /hackerrank_cli-2026.10.30/tests/test_help/test_help_questions_upload_.txt +0 -0
  76. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/tests/test_http.py +0 -0
  77. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/tests/test_sources.py +0 -0
  78. {hackerrank_cli-2026.10.7 → hackerrank_cli-2026.10.30}/zizmor.yml +0 -0
@@ -3,6 +3,8 @@ version: 2
3
3
 
4
4
  updates:
5
5
  - package-ecosystem: uv
6
+ allow:
7
+ - dependency-type: all
6
8
  directory: /
7
9
  schedule:
8
10
  interval: daily
@@ -2,8 +2,7 @@
2
2
  name: autofix.ci
3
3
 
4
4
  on:
5
- pull_request:
6
- branches: [main]
5
+ pull_request: {}
7
6
  push:
8
7
  branches: [main]
9
8
 
@@ -18,9 +17,9 @@ jobs:
18
17
  with:
19
18
  fetch-depth: 0
20
19
  persist-credentials: false
21
- - uses: astral-sh/setup-uv@v10.2.0
20
+ - uses: astral-sh/setup-uv@v10.3.2
22
21
  with:
23
- version: 0.12.19
22
+ version: 0.13.0
24
23
  python-version: '3.13'
25
24
  - name: Run repository fixers and checks
26
25
  run: uv run --locked prek run --all-files --stage pre-commit --no-fail-fast
@@ -47,9 +47,9 @@ jobs:
47
47
  with:
48
48
  persist-credentials: false
49
49
  fetch-depth: 0
50
- - uses: astral-sh/setup-uv@v10.2.0
50
+ - uses: astral-sh/setup-uv@v10.3.2
51
51
  with:
52
- version: 0.12.19
52
+ version: 0.13.0
53
53
  python-version: '3.13'
54
54
  - name: Require release credentials
55
55
  if: runner.os == 'macOS' && inputs.notarize
@@ -65,8 +65,9 @@ jobs:
65
65
  : "${APPLE_ID:?Missing APPLE_ID}" "${APPLE_TEAM_ID:?Missing APPLE_TEAM_ID}" "${APPLE_APP_PASSWORD:?Missing APPLE_APP_PASSWORD}"
66
66
  # The action removes its temporary keychain in its post step.
67
67
  - name: Import the Developer ID certificate
68
+ id: signing_certificate
68
69
  if: runner.os == 'macOS' && inputs.notarize
69
- uses: Apple-Actions/import-codesign-certs@5142e029c445c10ffc7149d172e540235a065466 # v7.0.0
70
+ uses: Apple-Actions/import-codesign-certs@77ba2a2a8f5cfc8c405ebf3159f767c323e238f9 # v7.1.0
70
71
  with:
71
72
  p12-file-base64: ${{ secrets.DEVELOPER_ID_APP_CERT_P12_BASE64 }}
72
73
  p12-password: ${{ secrets.DEVELOPER_ID_APP_CERT_PASSWORD }}
@@ -75,12 +76,19 @@ jobs:
75
76
  env:
76
77
  NAME: ${{ matrix.name }}
77
78
  NOTARIZE: ${{ inputs.notarize }}
79
+ IDENTITIES: ${{ steps.signing_certificate.outputs.identities }}
78
80
  run: |
79
81
  signing=()
80
82
  if [ "$RUNNER_OS" = macOS ] && [ "$NOTARIZE" = true ]; then
81
83
  # Sign embedded libraries before packing the one-file archive.
82
84
  # PyInstaller enables the hardened runtime and secure timestamp.
83
- signing=(--codesign-identity "Developer ID Application")
85
+ signing_identity="$(jq -er '
86
+ [.[] | select(.name | startswith("Developer ID Application:"))]
87
+ | if length == 1 then .[0].hash
88
+ else error("Expected exactly one Developer ID Application identity; found \(length)")
89
+ end
90
+ ' <<< "$IDENTITIES")"
91
+ signing=(--codesign-identity "$signing_identity")
84
92
  fi
85
93
  uv run --locked --group binary pyinstaller --clean --onefile --copy-metadata hackerrank-cli --name "$NAME" "${signing[@]}" bin/hackerrank_wrapper.py
86
94
  - name: Verify Developer ID signature
@@ -16,7 +16,7 @@ jobs:
16
16
  tests:
17
17
  strategy:
18
18
  matrix:
19
- python: ['3.13', '3.14']
19
+ python: ['3.13', '3.14', '3.15']
20
20
  os: [ubuntu-latest, macos-latest, windows-latest]
21
21
  runs-on: ${{ matrix.os }}
22
22
  steps:
@@ -24,9 +24,9 @@ jobs:
24
24
  with:
25
25
  persist-credentials: false
26
26
  fetch-depth: 0
27
- - uses: astral-sh/setup-uv@v10.2.0
27
+ - uses: astral-sh/setup-uv@v10.3.2
28
28
  with:
29
- version: 0.12.19
29
+ version: 0.13.0
30
30
  python-version: ${{ matrix.python }}
31
31
  enable-cache: true
32
32
  - run: uv run --locked pytest
@@ -37,13 +37,17 @@ jobs:
37
37
  with:
38
38
  persist-credentials: false
39
39
  fetch-depth: 0
40
- - uses: astral-sh/setup-uv@v10.2.0
40
+ - uses: astral-sh/setup-uv@v10.3.2
41
41
  with:
42
- version: 0.12.19
42
+ version: 0.13.0
43
43
  python-version: '3.13'
44
44
  - run: uv build
45
45
  - run: uv run --locked twine check dist/*
46
46
  - run: uv run --locked check-wheel-contents dist/*.whl
47
+ - name: Check release notes exist
48
+ run: |
49
+ RELEASE_VERSION="$(cat VERSION)"
50
+ test -s "docs/source/changelog/$RELEASE_VERSION.md"
47
51
  - name: Smoke installed wheel
48
52
  run: |
49
53
  uv venv /tmp/hackerrank-wheel
@@ -19,9 +19,9 @@ jobs:
19
19
  with:
20
20
  persist-credentials: false
21
21
  fetch-depth: 0
22
- - uses: astral-sh/setup-uv@v10.2.0
22
+ - uses: astral-sh/setup-uv@v10.3.2
23
23
  with:
24
- version: 0.12.19
24
+ version: 0.13.0
25
25
  python-version: '3.13'
26
26
  - run: uv run --locked prek run --all-files --stage manual --group docs
27
27
  - run: uv run --locked towncrier build --draft --version unreleased
@@ -27,9 +27,9 @@ jobs:
27
27
  with:
28
28
  persist-credentials: false
29
29
  fetch-depth: 0
30
- - uses: astral-sh/setup-uv@v10.2.0
30
+ - uses: astral-sh/setup-uv@v10.3.2
31
31
  with:
32
- version: 0.12.19
32
+ version: 0.13.0
33
33
  python-version: '3.13'
34
34
  enable-cache: true
35
35
  - run: uv run --locked prek run --all-files --no-fail-fast
@@ -23,9 +23,9 @@ jobs:
23
23
  with:
24
24
  persist-credentials: false
25
25
  fetch-depth: 0
26
- - uses: astral-sh/setup-uv@v10.2.0
26
+ - uses: astral-sh/setup-uv@v10.3.2
27
27
  with:
28
- version: 0.12.19
28
+ version: 0.13.0
29
29
  python-version: '3.13'
30
30
  - run: uv run --locked sphinx-build -W --keep-going -b html docs/source docs/build/html
31
31
  - uses: actions/configure-pages@v6
@@ -16,9 +16,9 @@ jobs:
16
16
  with:
17
17
  persist-credentials: false
18
18
  fetch-depth: 0
19
- - uses: astral-sh/setup-uv@v10.2.0
19
+ - uses: astral-sh/setup-uv@v10.3.2
20
20
  with:
21
- version: 0.12.19
21
+ version: 0.13.0
22
22
  python-version: '3.13'
23
23
  - run: uv run --locked pytest
24
24
  - run: uv run --locked prek run --all-files
@@ -27,10 +27,18 @@ jobs:
27
27
  - run: uv build
28
28
  - run: uv run --locked twine check dist/*
29
29
  - run: uv run --locked check-wheel-contents dist/*.whl
30
+ - name: Select the tagged release notes
31
+ env:
32
+ RELEASE_VERSION: ${{ github.ref_name }}
33
+ run: cp "docs/source/changelog/$RELEASE_VERSION.md" release-notes.md
30
34
  - uses: actions/upload-artifact@v7
31
35
  with:
32
36
  name: distributions
33
37
  path: dist/*
38
+ - uses: actions/upload-artifact@v7
39
+ with:
40
+ name: release-notes
41
+ path: release-notes.md
34
42
  binaries:
35
43
  # actionlint 1.7.12 accepts ./ for local workflows and rejects $/.
36
44
  uses: ./.github/workflows/binaries.yml # zizmor: ignore[self-repository]
@@ -60,18 +68,16 @@ jobs:
60
68
  permissions:
61
69
  contents: write
62
70
  steps:
63
- - uses: actions/checkout@v7
64
- with:
65
- persist-credentials: false
66
71
  - uses: actions/download-artifact@v8
67
72
  with:
68
73
  path: artifacts
69
74
  - name: Attach distributions and binaries
70
75
  env:
76
+ GH_REPO: ${{ github.repository }}
71
77
  GH_TOKEN: ${{ github.token }}
72
78
  TAG: ${{ github.ref_name }}
73
79
  run: gh release create "$TAG" artifacts/distributions/* artifacts/hackerrank-*/*
74
- --title "$TAG" --notes-file CHANGELOG.rst --verify-tag
80
+ --title "$TAG" --notes-file artifacts/release-notes/release-notes.md --verify-tag
75
81
  docker:
76
82
  needs: publish
77
83
  runs-on: ubuntu-latest
@@ -1,6 +1,6 @@
1
1
  FROM python:3.13-slim AS build
2
2
  LABEL org.opencontainers.image.source="https://github.com/adamtheturtle/hackerrank-cli"
3
- COPY --from=ghcr.io/astral-sh/uv:0.12.19 /uv /bin/uv
3
+ COPY --from=ghcr.io/astral-sh/uv:0.13.0 /uv /bin/uv
4
4
  WORKDIR /build
5
5
  COPY . .
6
6
  ARG HACKERRANK_CLI_VERSION=0.0.0
@@ -1,6 +1,6 @@
1
- include LICENSE README.rst CHANGELOG.rst
1
+ include LICENSE README.rst
2
2
  recursive-include src *.py *.typed
3
- recursive-include docs *.rst *.py
3
+ recursive-include docs *.rst *.md *.py
4
4
  recursive-include newsfragments *
5
5
  include .vale.ini prek.toml spelling_private_dict.txt zizmor.yml
6
6
  recursive-include styles/snapper *.yml
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hackerrank-cli
3
- Version: 2026.10.7
3
+ Version: 2026.10.30
4
4
  Summary: Upload starter files to existing HackerRank project questions.
5
5
  Author-email: Adam Dangoor <adamdangoor@gmail.com>
6
6
  License-Expression: MIT
@@ -14,11 +14,12 @@ Classifier: Operating System :: OS Independent
14
14
  Classifier: Programming Language :: Python :: 3 :: Only
15
15
  Classifier: Programming Language :: Python :: 3.13
16
16
  Classifier: Programming Language :: Python :: 3.14
17
+ Classifier: Programming Language :: Python :: 3.15
17
18
  Requires-Python: >=3.13
18
19
  Description-Content-Type: text/x-rst
19
20
  License-File: LICENSE
20
21
  Requires-Dist: click<8.6,>=8.3
21
- Requires-Dist: hackerrank>=2026.9.16
22
+ Requires-Dist: hackerrank>=2026.10.30
22
23
  Requires-Dist: httpx>=0.28
23
24
  Requires-Dist: httpx2>=2.12
24
25
  Requires-Dist: pathspec>=1
@@ -168,3 +169,18 @@ There are no prebuilt artifacts yet.
168
169
 
169
170
  See ``docs/source/migration.rst`` for migrating an existing shell uploader and
170
171
  keeping repository-specific snippet preparation outside this CLI.
172
+
173
+ Project AI system prompts
174
+ -------------------------
175
+
176
+ Set an existing project question's AI assistant prompt from a UTF-8 file:
177
+
178
+ .. code-block:: console
179
+
180
+ $ hackerrank questions set-system-prompt 123456 --prompt-file prompt.txt
181
+
182
+ Use ``--dry-run`` to validate without credentials or network access.
183
+ Prompts may contain up to 15,000 characters.
184
+ Text is sent exactly as read, including whitespace and line endings.
185
+ An empty file explicitly clears the prompt.
186
+ The command reads the question first to preserve its other metadata.
@@ -142,3 +142,18 @@ There are no prebuilt artifacts yet.
142
142
 
143
143
  See ``docs/source/migration.rst`` for migrating an existing shell uploader and
144
144
  keeping repository-specific snippet preparation outside this CLI.
145
+
146
+ Project AI system prompts
147
+ -------------------------
148
+
149
+ Set an existing project question's AI assistant prompt from a UTF-8 file:
150
+
151
+ .. code-block:: console
152
+
153
+ $ hackerrank questions set-system-prompt 123456 --prompt-file prompt.txt
154
+
155
+ Use ``--dry-run`` to validate without credentials or network access.
156
+ Prompts may contain up to 15,000 characters.
157
+ Text is sent exactly as read, including whitespace and line endings.
158
+ An empty file explicitly clears the prompt.
159
+ The command reads the question first to preserve its other metadata.
@@ -0,0 +1 @@
1
+ 2026.10.30
@@ -0,0 +1,7 @@
1
+ # 2026.10.1.1 (2026-10-01)
2
+
3
+ ## Features
4
+
5
+ - Upload existing HackerRank project-question starter files from a directory or
6
+ a single file, with nested ignore rules, configurable exclusions, offline dry
7
+ runs, and SDK retry handling.
@@ -0,0 +1,14 @@
1
+ # 2026.10.30 (2026-10-30)
2
+
3
+ ## Features
4
+
5
+ - Add `hackerrank questions set-system-prompt QUESTION_ID --prompt-file FILE`
6
+ for project AI prompts.
7
+ Validate UTF-8 text and the 15,000-character limit before network access,
8
+ preserve exact whitespace, and clear prompts with an empty file.
9
+ - Add support for Python 3.15.
10
+
11
+ ## Bug fixes
12
+
13
+ - Run validation workflows for pull requests targeting feature branches so
14
+ stacked changes receive the normal checks.
@@ -0,0 +1,7 @@
1
+ # 2026.10.7 (2026-10-07)
2
+
3
+ ## Features
4
+
5
+ - Export project ZIP archives offline with `hackerrank questions archive`,
6
+ using the same file selection and packaging as uploads.
7
+ ([#6](https://github.com/adamtheturtle/hackerrank-cli/issues/6))
@@ -0,0 +1,6 @@
1
+ # 2026.10.8 (2026-10-08)
2
+
3
+ ## Bug fixes
4
+
5
+ - Render GitHub release notes correctly and include only that version's
6
+ changes.
@@ -0,0 +1,11 @@
1
+ # Changelog
2
+
3
+ Releases are assembled from `newsfragments/` using Towncrier.
4
+
5
+ ```{toctree}
6
+ :maxdepth: 1
7
+ :glob:
8
+ :reversed:
9
+
10
+ changelog/*
11
+ ```
@@ -5,7 +5,7 @@ import importlib.metadata
5
5
  project = "hackerrank-cli"
6
6
  author = "Adam Dangoor"
7
7
  release = importlib.metadata.version(distribution_name="hackerrank-cli")
8
- extensions = ["sphinx_click.ext", "sphinxcontrib.spelling"]
8
+ extensions = ["myst_parser", "sphinx_click.ext", "sphinxcontrib.spelling"]
9
9
  html_theme = "furo"
10
10
  nitpicky = True
11
11
  html_theme_options = {
@@ -6,13 +6,13 @@ This standalone repository follows ``coderpad-cli`` main at
6
6
  It adapts the src layout, Click entry points, setuptools-scm versions, uv
7
7
  lockfile, strict checks, 100% branch coverage, Sphinx, Towncrier, and
8
8
  distribution workflows.
9
- The SDK baseline is the released ``hackerrank==2026.9.16`` in ``uv.lock``.
9
+ The SDK baseline is the released ``hackerrank==2026.10.30`` in ``uv.lock``.
10
10
  Python 3.13 or later is required by the SDK.
11
11
 
12
12
  The released SDK exposes ``questions.upload_project_zip``.
13
- Its newer ``upload_project_directory`` helper is not yet released.
14
13
  This CLI prepares filtered ZIPs with the standard library and uses the public
15
14
  released SDK for multipart serialization and all API communication.
15
+ Project AI prompt updates use the SDK's question read and update methods.
16
16
  It does not import private SDK helpers or install an unreleased Git dependency.
17
17
 
18
18
  .. code-block:: shell
@@ -30,9 +30,9 @@ Tests use the real SDK with its public ``Transport`` interface and default
30
30
  HTTPX transport.
31
31
  No SDK methods are replaced and no live questions are mutated.
32
32
  RESPX intercepts the HTTP boundary and fails closed for unregistered requests.
33
- Tests inspect the actual multipart body and ZIP bytes, assert the absence of
34
- metadata updates, preserve text, binary contents and executable bits, and
35
- exercise SDK retries with immutable archive bytes.
33
+ Upload tests inspect the actual multipart body and ZIP bytes, assert the
34
+ absence of metadata updates, preserve text, binary contents and executable
35
+ bits, and exercise SDK retries with immutable archive bytes.
36
36
 
37
37
  The SDK's checked-in Swagger specification does not describe the
38
38
  ``upload_project_zip`` endpoint.
@@ -40,18 +40,27 @@ The upload tests so assert the released SDK's actual wire behavior instead of
40
40
  inventing an OpenAPI schema.
41
41
  No separate mock-spec repository is needed for this scope.
42
42
 
43
- Add a Towncrier feature or bugfix fragment for each user-visible change.
43
+ Add a Towncrier feature or bugfix fragment in Markdown for each user-visible
44
+ change, such as ``newsfragments/123.bugfix.md``.
44
45
 
45
46
  Versions derive from Git tags using setuptools-scm.
46
47
  Untagged builds have a development version.
47
48
  Use date-based tags such as ``2026.10.7`` for releases.
48
49
  Before tagging a release, assemble notes with
49
- ``uv run towncrier build --yes --version VERSION``, commit the changelog, then
50
- write the same version to ``VERSION``, commit it, then tag the commit.
50
+ ``uv run towncrier build --yes --version VERSION``, commit the generated notes
51
+ in ``docs/source/changelog/VERSION.md``, then write the same version to
52
+ ``VERSION``, commit it, then tag the commit.
51
53
  Pushing a tag is the explicit publication trigger.
52
54
  The release workflow builds and checks packages, builds three standalone
53
55
  binaries, and then publishes to PyPI, GitHub Releases, and GHCR.
54
56
 
57
+ Towncrier writes a separate Markdown file for each release.
58
+ Sphinx reads those files through MyST and lists them in the changelog.
59
+ The release workflow uploads the tagged version's file directly as its GitHub
60
+ release notes.
61
+ Pull requests check that the notes for ``VERSION`` exist.
62
+ Review the generated Markdown before pushing a release tag.
63
+
55
64
  Local builds
56
65
  ------------
57
66
 
@@ -597,7 +597,7 @@ hooks = [
597
597
  name = "linkcheck",
598
598
  entry = "uv run --locked --group=dev sphinx-build -M linkcheck docs/source docs/build -W --keep-going -d docs/build/.doctrees-linkcheck",
599
599
  language = "system",
600
- types_or = ["rst"],
600
+ types_or = ["rst", "markdown"],
601
601
  stages = ["manual"],
602
602
  groups = ["docs"],
603
603
  priority = 610,
@@ -609,7 +609,7 @@ hooks = [
609
609
  name = "spelling",
610
610
  entry = "uv run --locked --group=dev sphinx-build -M spelling docs/source docs/build -W -d docs/build/.doctrees-spelling",
611
611
  language = "system",
612
- types_or = ["rst"],
612
+ types_or = ["rst", "markdown"],
613
613
  stages = ["manual"],
614
614
  groups = ["docs"],
615
615
  priority = 610,
@@ -18,9 +18,10 @@ classifiers = [
18
18
  "Programming Language :: Python :: 3 :: Only",
19
19
  "Programming Language :: Python :: 3.13",
20
20
  "Programming Language :: Python :: 3.14",
21
+ "Programming Language :: Python :: 3.15",
21
22
  ]
22
23
  dynamic = [ "version" ]
23
- dependencies = [ "click>=8.3,<8.6", "hackerrank>=2026.9.16", "httpx>=0.28", "httpx2>=2.12", "pathspec>=1" ]
24
+ dependencies = [ "click>=8.3,<8.6", "hackerrank>=2026.10.30", "httpx>=0.28", "httpx2>=2.12", "pathspec>=1" ]
24
25
  urls.Documentation = "https://adamtheturtle.github.io/hackerrank-cli/"
25
26
  urls.Issues = "https://github.com/adamtheturtle/hackerrank-cli/issues"
26
27
  urls.Source = "https://github.com/adamtheturtle/hackerrank-cli"
@@ -38,15 +39,16 @@ dev = [
38
39
  "furo==2025.12.19",
39
40
  "interrogate==1.7.0",
40
41
  "mypy==2.4.0",
41
- "mypy-pytest-parametrize==2026.10.5",
42
- "mypy-strict-kwargs==2026.8.25.1",
42
+ "mypy-pytest-parametrize==2026.10.5.1",
43
+ "mypy-strict-kwargs==2026.10.19",
44
+ "myst-parser==5.1.0",
43
45
  "no-defaults==2026.9.1",
44
- "prek==0.5.4",
46
+ "prek==0.5.7",
45
47
  "pydocstringformatter==1.0.0",
46
- "pylint[spelling]==4.0.9",
47
- "pylint-per-file-ignores==3.2.1",
48
- "pyproject-fmt==2.29.4",
49
- "pyrefly==1.3.1",
48
+ "pylint[spelling]==4.1.3",
49
+ "pylint-per-file-ignores==4.0.0",
50
+ "pyproject-fmt==2.30.3",
51
+ "pyrefly==1.4.0",
50
52
  "pyright==1.1.414",
51
53
  "pyroma==5.0.1",
52
54
  "pytest==9.1.1",
@@ -55,24 +57,24 @@ dev = [
55
57
  "pytest-regressions==2.11.0",
56
58
  "pytest-xdist==3.8.0",
57
59
  "respx==0.23.1",
58
- "ruff==0.16.9",
60
+ "ruff==0.17.2",
59
61
  "setuptools>=77",
60
62
  "setuptools-scm>=8.1",
61
63
  "shellcheck-py==0.11.0.1",
62
64
  "shfmt-py==4.2.0",
63
- "snapper-fmt==0.11.7",
65
+ "snapper-fmt==0.11.10",
64
66
  "sphinx>=8.1.3",
65
67
  "sphinx-click==6.2",
66
68
  "sphinx-lint==1.0.2",
67
69
  "sphinxcontrib-spelling==8.0.2",
68
- "strict-kwargs==2026.8.28.post2",
70
+ "strict-kwargs==2026.10.9",
69
71
  "towncrier==26.9",
70
72
  "twine==7.0.0",
71
- "ty==0.0.84",
72
- "vale==3.22.0.0",
73
+ "ty==0.0.92",
74
+ "vale==3.25.1.0",
73
75
  "vulture==2.16",
74
76
  "yamlfix==1.19.1",
75
- "zizmor==1.30.1",
77
+ "zizmor==1.31.1",
76
78
  ]
77
79
  binary = [ "pyinstaller>=6.12" ]
78
80
 
@@ -86,7 +88,8 @@ version_file = "src/hackerrank_cli/_version.py"
86
88
  version_scheme = "post-release"
87
89
 
88
90
  [tool.uv]
89
- required-version = "==0.12.19"
91
+ # Dependabot currently ships uv 0.12.18; CI pins uv separately.
92
+ required-version = ">=0.12.18"
90
93
 
91
94
  [tool.ruff]
92
95
  line-length = 79
@@ -190,7 +193,7 @@ ignore_names = [
190
193
 
191
194
  [tool.pyproject-fmt]
192
195
  keep_full_version = true
193
- max_supported_python = "3.14"
196
+ max_supported_python = "3.15"
194
197
 
195
198
  [tool.mypy]
196
199
  files = [ "." ]
@@ -200,6 +203,7 @@ follow_untyped_imports = true
200
203
  python_version = "3.13"
201
204
  strict = true
202
205
  plugins = [ "mypy_pytest_parametrize", "mypy_strict_kwargs" ]
206
+ show_traceback = true
203
207
  num_workers = "auto"
204
208
 
205
209
  [tool.pyrefly]
@@ -241,10 +245,10 @@ report.show_missing = true
241
245
 
242
246
  [tool.towncrier]
243
247
  directory = "newsfragments"
244
- filename = "CHANGELOG.rst"
245
- title_format = "{version} ({project_date})"
246
- issue_format = "#{issue}"
247
- underlines = [ "-", "~", "^" ]
248
+ filename = "docs/source/changelog/{version}.md"
249
+ title_format = "# {version} ({project_date})"
250
+ issue_format = "[#{issue}](https://github.com/adamtheturtle/hackerrank-cli/issues/{issue})"
251
+ single_file = false
248
252
  ignore = [ ".gitkeep" ]
249
253
  type = [
250
254
  { directory = "feature", name = "Features", showcontent = true },