KG-ARCHMAP 0.6.0b0__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 (153) hide show
  1. kg_archmap-0.6.0b0/.archmap.toml +7 -0
  2. kg_archmap-0.6.0b0/.editorconfig +12 -0
  3. kg_archmap-0.6.0b0/.gitattributes +1 -0
  4. kg_archmap-0.6.0b0/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  5. kg_archmap-0.6.0b0/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
  6. kg_archmap-0.6.0b0/.github/PULL_REQUEST_TEMPLATE.md +28 -0
  7. kg_archmap-0.6.0b0/.github/workflows/ci.yml +51 -0
  8. kg_archmap-0.6.0b0/.github/workflows/docs.yml +65 -0
  9. kg_archmap-0.6.0b0/.github/workflows/publish.yml +49 -0
  10. kg_archmap-0.6.0b0/.github/workflows/release.yml +220 -0
  11. kg_archmap-0.6.0b0/.gitignore +27 -0
  12. kg_archmap-0.6.0b0/CHANGELOG.md +190 -0
  13. kg_archmap-0.6.0b0/CODE_OF_CONDUCT.md +43 -0
  14. kg_archmap-0.6.0b0/CONTRIBUTING.md +96 -0
  15. kg_archmap-0.6.0b0/LICENSE +21 -0
  16. kg_archmap-0.6.0b0/NOTICE.md +15 -0
  17. kg_archmap-0.6.0b0/PKG-INFO +263 -0
  18. kg_archmap-0.6.0b0/README.md +203 -0
  19. kg_archmap-0.6.0b0/ROADMAP.md +26 -0
  20. kg_archmap-0.6.0b0/archmap.spec +39 -0
  21. kg_archmap-0.6.0b0/docs/BRANCHING.md +36 -0
  22. kg_archmap-0.6.0b0/docs/MIGRATION_TO_PYTHON.md +38 -0
  23. kg_archmap-0.6.0b0/docs/api.md +112 -0
  24. kg_archmap-0.6.0b0/docs/architecture.md +163 -0
  25. kg_archmap-0.6.0b0/docs/changelog.md +6 -0
  26. kg_archmap-0.6.0b0/docs/cli/analyze.md +65 -0
  27. kg_archmap-0.6.0b0/docs/cli/diff.md +77 -0
  28. kg_archmap-0.6.0b0/docs/cli/explain.md +35 -0
  29. kg_archmap-0.6.0b0/docs/cli/improve.md +37 -0
  30. kg_archmap-0.6.0b0/docs/cli/init.md +37 -0
  31. kg_archmap-0.6.0b0/docs/cli/risk.md +36 -0
  32. kg_archmap-0.6.0b0/docs/cli/serve.md +56 -0
  33. kg_archmap-0.6.0b0/docs/cli/watch.md +47 -0
  34. kg_archmap-0.6.0b0/docs/code-of-conduct.md +7 -0
  35. kg_archmap-0.6.0b0/docs/contributing.md +15 -0
  36. kg_archmap-0.6.0b0/docs/getting-started/demo.md +37 -0
  37. kg_archmap-0.6.0b0/docs/getting-started/installation.md +61 -0
  38. kg_archmap-0.6.0b0/docs/getting-started/quickstart.md +75 -0
  39. kg_archmap-0.6.0b0/docs/index.md +57 -0
  40. kg_archmap-0.6.0b0/docs/notice.md +14 -0
  41. kg_archmap-0.6.0b0/docs/operations/logging.md +21 -0
  42. kg_archmap-0.6.0b0/docs/roadmap.md +23 -0
  43. kg_archmap-0.6.0b0/examples/README.md +34 -0
  44. kg_archmap-0.6.0b0/examples/sample-project/__init__.py +13 -0
  45. kg_archmap-0.6.0b0/examples/sample-project/a.py +4 -0
  46. kg_archmap-0.6.0b0/examples/sample-project/app/controller.py +8 -0
  47. kg_archmap-0.6.0b0/examples/sample-project/app/service.py +10 -0
  48. kg_archmap-0.6.0b0/examples/sample-project/b.py +4 -0
  49. kg_archmap-0.6.0b0/examples/sample-project/c.py +1 -0
  50. kg_archmap-0.6.0b0/examples/sample-project/cli/main.py +7 -0
  51. kg_archmap-0.6.0b0/examples/sample-project/core/models.py +13 -0
  52. kg_archmap-0.6.0b0/examples/sample-project/core/validators.py +9 -0
  53. kg_archmap-0.6.0b0/examples/sample-project/utils/logger.py +10 -0
  54. kg_archmap-0.6.0b0/logs/README.md +13 -0
  55. kg_archmap-0.6.0b0/logs/archive/server_log_legacy_2026-03-11.txt +1 -0
  56. kg_archmap-0.6.0b0/logs/archive/test_out_legacy_2026-03-11.txt +18 -0
  57. kg_archmap-0.6.0b0/logs/runtime/.gitkeep +1 -0
  58. kg_archmap-0.6.0b0/mkdocs.yml +85 -0
  59. kg_archmap-0.6.0b0/package-lock.json +1056 -0
  60. kg_archmap-0.6.0b0/package.json +43 -0
  61. kg_archmap-0.6.0b0/pyproject.toml +68 -0
  62. kg_archmap-0.6.0b0/resources/icon.png +0 -0
  63. kg_archmap-0.6.0b0/scripts/benchmark.py +92 -0
  64. kg_archmap-0.6.0b0/scripts/build-exe.ps1 +88 -0
  65. kg_archmap-0.6.0b0/scripts/demo.ps1 +25 -0
  66. kg_archmap-0.6.0b0/scripts/run-smoke.ps1 +13 -0
  67. kg_archmap-0.6.0b0/src/archmap/__init__.py +5 -0
  68. kg_archmap-0.6.0b0/src/archmap/__main__.py +6 -0
  69. kg_archmap-0.6.0b0/src/archmap/cli/__init__.py +1 -0
  70. kg_archmap-0.6.0b0/src/archmap/cli/args.py +258 -0
  71. kg_archmap-0.6.0b0/src/archmap/cli/commands.py +449 -0
  72. kg_archmap-0.6.0b0/src/archmap/cli/defaults.py +8 -0
  73. kg_archmap-0.6.0b0/src/archmap/cli/main.py +119 -0
  74. kg_archmap-0.6.0b0/src/archmap/cli/reporting.py +427 -0
  75. kg_archmap-0.6.0b0/src/archmap/cli/server.py +401 -0
  76. kg_archmap-0.6.0b0/src/archmap/config.py +187 -0
  77. kg_archmap-0.6.0b0/src/archmap/core/__init__.py +28 -0
  78. kg_archmap-0.6.0b0/src/archmap/core/analyzer/__init__.py +16 -0
  79. kg_archmap-0.6.0b0/src/archmap/core/analyzer/architecture_analyzer.py +373 -0
  80. kg_archmap-0.6.0b0/src/archmap/core/analyzer/architecture_suggester.py +366 -0
  81. kg_archmap-0.6.0b0/src/archmap/core/analyzer/complexity_analyzer.py +168 -0
  82. kg_archmap-0.6.0b0/src/archmap/core/analyzer/cycle_detector.py +91 -0
  83. kg_archmap-0.6.0b0/src/archmap/core/analyzer/dependency_graph.py +117 -0
  84. kg_archmap-0.6.0b0/src/archmap/core/analyzer/diff_analyzer.py +304 -0
  85. kg_archmap-0.6.0b0/src/archmap/core/analyzer/history_analyzer.py +314 -0
  86. kg_archmap-0.6.0b0/src/archmap/core/analyzer/human_analyzer.py +81 -0
  87. kg_archmap-0.6.0b0/src/archmap/core/analyzer/impact_analyzer.py +39 -0
  88. kg_archmap-0.6.0b0/src/archmap/core/analyzer/project_explainer.py +108 -0
  89. kg_archmap-0.6.0b0/src/archmap/core/analyzer/risk_analyzer.py +126 -0
  90. kg_archmap-0.6.0b0/src/archmap/core/graph/__init__.py +3 -0
  91. kg_archmap-0.6.0b0/src/archmap/core/graph/graph_builder.py +69 -0
  92. kg_archmap-0.6.0b0/src/archmap/core/parser/__init__.py +103 -0
  93. kg_archmap-0.6.0b0/src/archmap/core/parser/bootstrap.py +51 -0
  94. kg_archmap-0.6.0b0/src/archmap/core/parser/cpp_parser.py +63 -0
  95. kg_archmap-0.6.0b0/src/archmap/core/parser/csharp_parser.py +34 -0
  96. kg_archmap-0.6.0b0/src/archmap/core/parser/go_parser.py +61 -0
  97. kg_archmap-0.6.0b0/src/archmap/core/parser/java_parser.py +34 -0
  98. kg_archmap-0.6.0b0/src/archmap/core/parser/js_parser.py +490 -0
  99. kg_archmap-0.6.0b0/src/archmap/core/parser/php_parser.py +46 -0
  100. kg_archmap-0.6.0b0/src/archmap/core/parser/project_parser.py +195 -0
  101. kg_archmap-0.6.0b0/src/archmap/core/parser/python_parser.py +81 -0
  102. kg_archmap-0.6.0b0/src/archmap/core/parser/registry.py +50 -0
  103. kg_archmap-0.6.0b0/src/archmap/core/parser/resolvers.py +528 -0
  104. kg_archmap-0.6.0b0/src/archmap/core/parser/rust_parser.py +56 -0
  105. kg_archmap-0.6.0b0/src/archmap/core/parser/ts_parser.py +11 -0
  106. kg_archmap-0.6.0b0/src/archmap/exporters/__init__.py +9 -0
  107. kg_archmap-0.6.0b0/src/archmap/exporters/cytoscape_exporter.py +26 -0
  108. kg_archmap-0.6.0b0/src/archmap/exporters/json_exporter.py +30 -0
  109. kg_archmap-0.6.0b0/src/archmap/exporters/mermaid_exporter.py +93 -0
  110. kg_archmap-0.6.0b0/src/archmap/py.typed +1 -0
  111. kg_archmap-0.6.0b0/src/archmap/utils/__init__.py +1 -0
  112. kg_archmap-0.6.0b0/src/archmap/utils/file_utils.py +160 -0
  113. kg_archmap-0.6.0b0/src/archmap/utils/layers.py +39 -0
  114. kg_archmap-0.6.0b0/src/archmap/web-ui/__init__.py +0 -0
  115. kg_archmap-0.6.0b0/src/archmap/web-ui/static/app.js +2660 -0
  116. kg_archmap-0.6.0b0/src/archmap/web-ui/static/i18n.js +632 -0
  117. kg_archmap-0.6.0b0/src/archmap/web-ui/static/index.html +512 -0
  118. kg_archmap-0.6.0b0/src/archmap/web-ui/static/styles.css +299 -0
  119. kg_archmap-0.6.0b0/tests/conftest.py +146 -0
  120. kg_archmap-0.6.0b0/tests/test_analyzer.py +75 -0
  121. kg_archmap-0.6.0b0/tests/test_architecture_analyzer.py +129 -0
  122. kg_archmap-0.6.0b0/tests/test_architecture_suggester.py +124 -0
  123. kg_archmap-0.6.0b0/tests/test_bootstrap_lazy.py +43 -0
  124. kg_archmap-0.6.0b0/tests/test_cli.py +104 -0
  125. kg_archmap-0.6.0b0/tests/test_cli_args.py +142 -0
  126. kg_archmap-0.6.0b0/tests/test_cli_commands.py +531 -0
  127. kg_archmap-0.6.0b0/tests/test_cli_init.py +122 -0
  128. kg_archmap-0.6.0b0/tests/test_cli_internal.py +218 -0
  129. kg_archmap-0.6.0b0/tests/test_cli_reporting.py +310 -0
  130. kg_archmap-0.6.0b0/tests/test_cli_server.py +347 -0
  131. kg_archmap-0.6.0b0/tests/test_cli_watch.py +47 -0
  132. kg_archmap-0.6.0b0/tests/test_config.py +185 -0
  133. kg_archmap-0.6.0b0/tests/test_cpp_parser.py +83 -0
  134. kg_archmap-0.6.0b0/tests/test_csharp_parser.py +71 -0
  135. kg_archmap-0.6.0b0/tests/test_cycle_detector.py +31 -0
  136. kg_archmap-0.6.0b0/tests/test_diff.py +174 -0
  137. kg_archmap-0.6.0b0/tests/test_e2e_analyze.py +25 -0
  138. kg_archmap-0.6.0b0/tests/test_e2e_diff.py +28 -0
  139. kg_archmap-0.6.0b0/tests/test_e2e_history.py +36 -0
  140. kg_archmap-0.6.0b0/tests/test_exporters.py +127 -0
  141. kg_archmap-0.6.0b0/tests/test_file_utils.py +107 -0
  142. kg_archmap-0.6.0b0/tests/test_go_resolver.py +70 -0
  143. kg_archmap-0.6.0b0/tests/test_history_analyzer.py +53 -0
  144. kg_archmap-0.6.0b0/tests/test_java_parser.py +90 -0
  145. kg_archmap-0.6.0b0/tests/test_multi_language.py +71 -0
  146. kg_archmap-0.6.0b0/tests/test_parser_dependencies.py +101 -0
  147. kg_archmap-0.6.0b0/tests/test_parser_internal.py +194 -0
  148. kg_archmap-0.6.0b0/tests/test_parsers.py +164 -0
  149. kg_archmap-0.6.0b0/tests/test_php_parser.py +89 -0
  150. kg_archmap-0.6.0b0/tests/test_risk_layers.py +128 -0
  151. kg_archmap-0.6.0b0/web-ui/README.md +30 -0
  152. kg_archmap-0.6.0b0/web-ui/dev-server.js +62 -0
  153. kg_archmap-0.6.0b0/web-ui/server.js +492 -0
@@ -0,0 +1,7 @@
1
+ [architecture.rules]
2
+ forbid = [
3
+ "core -> cli",
4
+ "parser -> cli",
5
+ "analyzer -> cli",
6
+ "graph -> cli",
7
+ ]
@@ -0,0 +1,12 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ insert_final_newline = true
7
+ indent_style = space
8
+ indent_size = 2
9
+ trim_trailing_whitespace = true
10
+
11
+ [*.md]
12
+ trim_trailing_whitespace = false
@@ -0,0 +1 @@
1
+ * text=auto eol=lf
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: Bug report
3
+ about: Report something that is broken or behaving unexpectedly
4
+ title: "[bug] "
5
+ labels: bug
6
+ assignees: ""
7
+ ---
8
+
9
+ ## Describe the bug
10
+
11
+ A clear and concise description of what the bug is.
12
+
13
+ ## To reproduce
14
+
15
+ Steps to reproduce the behavior:
16
+
17
+ 1. Run command: `archmap ...`
18
+ 2. With project at path: `...`
19
+ 3. See error
20
+
21
+ ## Expected behavior
22
+
23
+ What you expected to happen.
24
+
25
+ ## Actual behavior
26
+
27
+ What actually happened. Include the full error message / stack trace if available.
28
+
29
+ ## Environment
30
+
31
+ - OS: <!-- e.g. Ubuntu 22.04, Windows 11, macOS 14 -->
32
+ - Python version: <!-- e.g. 3.11.9 -->
33
+ - ArchMAP version: <!-- `archmap version` output -->
34
+ - Install method: <!-- pip install / pip install -e / .exe bundle -->
35
+
36
+ ## Additional context
37
+
38
+ Any other context, screenshots, or sample project structure that helps reproduce the issue.
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea or improvement for ArchMAP
4
+ title: "[feat] "
5
+ labels: enhancement
6
+ assignees: ""
7
+ ---
8
+
9
+ ## Problem / motivation
10
+
11
+ What problem does this feature solve? Who is affected?
12
+
13
+ ## Proposed solution
14
+
15
+ A clear description of what you want to happen.
16
+
17
+ ## Alternatives considered
18
+
19
+ Other approaches you have thought about and why you ruled them out.
20
+
21
+ ## Additional context
22
+
23
+ Any mockups, examples from other tools, or related issues.
@@ -0,0 +1,28 @@
1
+ ## Summary
2
+
3
+ Describe the purpose of this PR in 2-5 lines.
4
+
5
+ ## Branch Flow
6
+
7
+ - Source branch: `feat/*` or `fix/*` or `docs/*`
8
+ - Target branch: `dev` (default) or `release/*` (stabilization only)
9
+
10
+ ## Checklist
11
+
12
+ - [ ] I ran `python -m ruff check .`
13
+ - [ ] I ran `python -m pytest -q`
14
+ - [ ] I ran smoke analysis:
15
+ - `python -m archmap.cli.main analyze . --format both --out .codeatlas/local-graph.json --out-mermaid .codeatlas/local-graph.mmd --include-cytoscape`
16
+ - [ ] I updated docs/changelog when behavior changed
17
+ - [ ] I did not commit local runtime logs or build artifacts
18
+ - [ ] I preserved attribution files (`LICENSE`, `NOTICE.md`)
19
+
20
+ ## Impact
21
+
22
+ - Breaking change: `yes` / `no`
23
+ - New CLI flags/endpoints:
24
+ - Risk to release:
25
+
26
+ ## Validation Notes
27
+
28
+ Paste key command outputs or explain test coverage for this PR.
@@ -0,0 +1,51 @@
1
+ name: ci
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - dev
8
+ - feat/**
9
+ - release/**
10
+ - feature/**
11
+ - fix/**
12
+ - docs/**
13
+ pull_request:
14
+
15
+ jobs:
16
+ quality:
17
+ runs-on: ubuntu-latest
18
+ strategy:
19
+ matrix:
20
+ python-version: ["3.11", "3.12", "3.13"]
21
+ steps:
22
+ - name: Checkout
23
+ uses: actions/checkout@v4
24
+
25
+ - name: Setup Python ${{ matrix.python-version }}
26
+ uses: actions/setup-python@v5
27
+ with:
28
+ python-version: ${{ matrix.python-version }}
29
+
30
+ - name: Install dependencies
31
+ run: |
32
+ python -m pip install --upgrade pip
33
+ python -m pip install -e ".[dev]"
34
+
35
+ - name: Lint
36
+ run: python -m ruff check .
37
+
38
+ - name: Run tests with coverage
39
+ run: python -m pytest
40
+
41
+ - name: Run smoke analysis
42
+ run: python -m archmap.cli.main analyze . --format both --out .codeatlas/ci-graph.json --out-mermaid .codeatlas/ci-graph.mmd --include-cytoscape
43
+ if: matrix.python-version == '3.13'
44
+
45
+ - name: Enforce architecture gate
46
+ if: matrix.python-version == '3.13'
47
+ run: python -m archmap.cli.main analyze . --format json --out .codeatlas/ci-gate.json --fail-on-cycles --fail-on-custom-rules --min-health 65
48
+
49
+ - name: Run architecture history smoke
50
+ if: matrix.python-version == '3.13'
51
+ run: python -m archmap.cli.main history --repo . --limit 8 --json > .codeatlas/ci-history.json
@@ -0,0 +1,65 @@
1
+ name: docs
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ paths:
8
+ - "docs/**"
9
+ - "mkdocs.yml"
10
+ - "README.md"
11
+ - "CHANGELOG.md"
12
+ - "ROADMAP.md"
13
+ - "CONTRIBUTING.md"
14
+ - "CODE_OF_CONDUCT.md"
15
+ workflow_dispatch:
16
+
17
+ permissions:
18
+ contents: read
19
+ pages: write
20
+ id-token: write
21
+
22
+ concurrency:
23
+ group: pages
24
+ cancel-in-progress: true
25
+
26
+ jobs:
27
+ deploy:
28
+ runs-on: ubuntu-latest
29
+ environment:
30
+ name: github-pages
31
+ url: ${{ steps.deployment.outputs.page_url }}
32
+ steps:
33
+ - name: Checkout
34
+ uses: actions/checkout@v4
35
+
36
+ - name: Configure GitHub Pages
37
+ uses: actions/configure-pages@v5
38
+
39
+ - name: Setup Python
40
+ uses: actions/setup-python@v5
41
+ with:
42
+ python-version: "3.13"
43
+
44
+ - name: Install MkDocs
45
+ run: |
46
+ pip install mkdocs-material
47
+
48
+ - name: Copy root docs into docs/ for MkDocs
49
+ run: |
50
+ cp CHANGELOG.md docs/changelog.md
51
+ cp ROADMAP.md docs/roadmap.md
52
+ cp CONTRIBUTING.md docs/contributing.md
53
+ cp CODE_OF_CONDUCT.md docs/code-of-conduct.md
54
+
55
+ - name: Build docs site
56
+ run: mkdocs build --strict
57
+
58
+ - name: Upload to GitHub Pages
59
+ uses: actions/upload-pages-artifact@v4
60
+ with:
61
+ path: site/
62
+
63
+ - name: Deploy to GitHub Pages
64
+ id: deployment
65
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,49 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*"]
6
+
7
+ jobs:
8
+ build:
9
+ name: Build distribution
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ with:
15
+ fetch-depth: 0
16
+
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.11"
20
+
21
+ - name: Install Hatch
22
+ run: pip install hatch
23
+
24
+ - name: Build wheel and sdist
25
+ run: hatch build
26
+
27
+ - name: Upload distribution artifacts
28
+ uses: actions/upload-artifact@v4
29
+ with:
30
+ name: dist
31
+ path: dist/
32
+
33
+ publish:
34
+ name: Publish to PyPI
35
+ needs: build
36
+ runs-on: ubuntu-latest
37
+ environment: pypi
38
+ permissions:
39
+ id-token: write
40
+
41
+ steps:
42
+ - name: Download distribution artifacts
43
+ uses: actions/download-artifact@v4
44
+ with:
45
+ name: dist
46
+ path: dist/
47
+
48
+ - name: Publish to PyPI
49
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,220 @@
1
+ name: release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ build-python:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: Checkout
16
+ uses: actions/checkout@v4
17
+
18
+ - name: Setup Python
19
+ uses: actions/setup-python@v5
20
+ with:
21
+ python-version: "3.13"
22
+
23
+ - name: Validate tag matches package version
24
+ shell: bash
25
+ run: |
26
+ TAG="${GITHUB_REF_NAME}"
27
+ VERSION="${TAG#v}"
28
+ PACKAGE_VERSION="$(python - <<'PY'
29
+ import sys
30
+ sys.path.insert(0, "src")
31
+ from archmap import __version__
32
+ print(__version__)
33
+ PY
34
+ )"
35
+ if [ "$VERSION" != "$PACKAGE_VERSION" ]; then
36
+ echo "::error::Tag version ($VERSION) does not match package version ($PACKAGE_VERSION)."
37
+ exit 1
38
+ fi
39
+
40
+ - name: Install build tools
41
+ run: |
42
+ python -m pip install --upgrade pip
43
+ python -m pip install build twine
44
+ python -m pip install -e ".[dev]"
45
+
46
+ - name: Run quality gates
47
+ run: |
48
+ python -m ruff check .
49
+ python -m pytest
50
+
51
+ - name: Build distribution
52
+ shell: bash
53
+ run: |
54
+ rm -rf build dist
55
+ python -m build --sdist --wheel
56
+
57
+ - name: Upload Python artifacts
58
+ uses: actions/upload-artifact@v4
59
+ with:
60
+ name: python-dist
61
+ path: |
62
+ dist/*.whl
63
+ dist/*.tar.gz
64
+ if-no-files-found: error
65
+
66
+ build-windows-exe:
67
+ runs-on: windows-latest
68
+ steps:
69
+ - name: Checkout
70
+ uses: actions/checkout@v4
71
+
72
+ - name: Setup Python
73
+ uses: actions/setup-python@v5
74
+ with:
75
+ python-version: "3.13"
76
+
77
+ - name: Validate tag matches package version
78
+ shell: pwsh
79
+ run: |
80
+ $tag = $env:GITHUB_REF_NAME
81
+ $version = $tag.Substring(1)
82
+ $packageVersion = (python -c "import sys; sys.path.insert(0, 'src'); from archmap import __version__; print(__version__)").Trim()
83
+ if ($version -ne $packageVersion) {
84
+ Write-Error "Tag version ($version) does not match package version ($packageVersion)."
85
+ exit 1
86
+ }
87
+
88
+ - name: Install build dependencies
89
+ run: |
90
+ python -m pip install --upgrade pip
91
+ python -m pip install pyinstaller
92
+ python -m pip install -e ".[dev]"
93
+
94
+ - name: Build Windows executable
95
+ shell: pwsh
96
+ run: |
97
+ $version = (python -c "import sys; sys.path.insert(0, 'src'); from archmap import __version__; print(__version__)").Trim()
98
+ if ([string]::IsNullOrWhiteSpace($version)) {
99
+ throw "Failed to resolve package version."
100
+ }
101
+
102
+ python -m PyInstaller src/archmap/cli/main.py `
103
+ --onefile `
104
+ --name archmap `
105
+ --paths src `
106
+ --noconfirm `
107
+ --clean `
108
+ --icon resources/icon.png `
109
+ --exclude-module tkinter `
110
+ --exclude-module _tkinter `
111
+ --add-data "src/archmap/web-ui/static;web-ui/static"
112
+
113
+ $pyinstallerExit = $LASTEXITCODE
114
+ if ($pyinstallerExit -ne 0 -and -not (Test-Path "dist/archmap.exe")) {
115
+ throw "PyInstaller failed with exit code $pyinstallerExit and EXE was not generated."
116
+ }
117
+ if ($pyinstallerExit -ne 0) {
118
+ Write-Warning "PyInstaller exited with code $pyinstallerExit but EXE exists. Continuing release."
119
+ }
120
+
121
+ Copy-Item "dist/archmap.exe" "dist/archmap-$version.exe" -Force
122
+
123
+ $sha = (Get-FileHash "dist/archmap.exe" -Algorithm SHA256).Hash
124
+ $manifest = @{
125
+ version = $version
126
+ builtAtUtc = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
127
+ exePath = "dist/archmap.exe"
128
+ versionedExe = "dist/archmap-$version.exe"
129
+ sha256 = $sha
130
+ } | ConvertTo-Json -Depth 4
131
+ Set-Content -Path "dist/archmap-build-info.json" -Value $manifest -Encoding UTF8
132
+
133
+ - name: Upload Windows artifacts
134
+ uses: actions/upload-artifact@v4
135
+ with:
136
+ name: windows-exe
137
+ path: |
138
+ dist/archmap.exe
139
+ dist/archmap-*.exe
140
+ dist/archmap-build-info.json
141
+ if-no-files-found: error
142
+
143
+ release:
144
+ runs-on: ubuntu-latest
145
+ needs:
146
+ - build-python
147
+ - build-windows-exe
148
+ permissions:
149
+ contents: write
150
+ steps:
151
+ - name: Checkout
152
+ uses: actions/checkout@v4
153
+
154
+ - name: Download Python artifacts
155
+ uses: actions/download-artifact@v4
156
+ with:
157
+ name: python-dist
158
+ path: dist
159
+
160
+ - name: Download Windows artifacts
161
+ uses: actions/download-artifact@v4
162
+ with:
163
+ name: windows-exe
164
+ path: dist
165
+
166
+ - name: Extract changelog for this release
167
+ id: changelog
168
+ shell: bash
169
+ env:
170
+ VERSION: ${{ github.ref_name }}
171
+ run: |
172
+ VERSION="${VERSION#v}"
173
+ export VERSION
174
+ python - <<'PY'
175
+ import os
176
+ import pathlib
177
+ import re
178
+
179
+ version = os.environ["VERSION"]
180
+ changelog = pathlib.Path("CHANGELOG.md")
181
+ text = changelog.read_text(encoding="utf-8")
182
+
183
+ header = re.compile(rf"^## \[{re.escape(version)}\](?:\s+-\s+.*)?$", re.MULTILINE)
184
+ match = header.search(text)
185
+ if not match:
186
+ notes = "See CHANGELOG.md for details."
187
+ else:
188
+ start = match.end()
189
+ next_header = re.search(r"^## \[", text[start:], re.MULTILINE)
190
+ end = start + next_header.start() if next_header else len(text)
191
+ notes = text[start:end].strip() or "See CHANGELOG.md for details."
192
+
193
+ pathlib.Path("release_notes.txt").write_text(notes + "\n", encoding="utf-8")
194
+ with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output:
195
+ output.write(f"version={version}\n")
196
+ PY
197
+
198
+ - name: Detect prerelease tag
199
+ id: release_meta
200
+ shell: bash
201
+ env:
202
+ VERSION: ${{ github.ref_name }}
203
+ run: |
204
+ VERSION="${VERSION#v}"
205
+ if [[ "$VERSION" =~ (a|b|rc|dev) ]]; then
206
+ echo "prerelease=true" >> "$GITHUB_OUTPUT"
207
+ else
208
+ echo "prerelease=false" >> "$GITHUB_OUTPUT"
209
+ fi
210
+
211
+ - name: Create GitHub Release
212
+ uses: softprops/action-gh-release@v2
213
+ with:
214
+ tag_name: ${{ github.ref_name }}
215
+ name: ArchMAP ${{ github.ref_name }}
216
+ prerelease: ${{ steps.release_meta.outputs.prerelease }}
217
+ body_path: release_notes.txt
218
+ files: dist/*
219
+ env:
220
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,27 @@
1
+ node_modules/
2
+ coverage/
3
+ dist/
4
+ build/
5
+ site/
6
+ *.log
7
+ .codeatlas/
8
+ .venv/
9
+ venv/
10
+ __pycache__/
11
+ .pytest_cache/
12
+ .ruff_cache/
13
+ .mypy_cache/
14
+ *.pyc
15
+ htmlcov/
16
+ .coverage
17
+ .coverage.*
18
+ logs/runtime/*
19
+ !logs/runtime/.gitkeep
20
+ server_log.txt
21
+ test_out.txt
22
+ test_output*.txt
23
+ cov_report*.txt
24
+ parser_cov*.txt
25
+ coverage.json
26
+ release_notes_api.txt
27
+ web-ui/static/