plugin-scanner 1.4.15__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 (180) hide show
  1. plugin_scanner-1.4.15/.clusterfuzzlite/Dockerfile +9 -0
  2. plugin_scanner-1.4.15/.clusterfuzzlite/build.sh +8 -0
  3. plugin_scanner-1.4.15/.clusterfuzzlite/project.yaml +3 -0
  4. plugin_scanner-1.4.15/.clusterfuzzlite/requirements-atheris.txt +1 -0
  5. plugin_scanner-1.4.15/.dockerignore +10 -0
  6. plugin_scanner-1.4.15/.github/CODEOWNERS +1 -0
  7. plugin_scanner-1.4.15/.github/dependabot.yml +12 -0
  8. plugin_scanner-1.4.15/.github/workflows/ci.yml +45 -0
  9. plugin_scanner-1.4.15/.github/workflows/codeql.yml +41 -0
  10. plugin_scanner-1.4.15/.github/workflows/e2e-test.yml +112 -0
  11. plugin_scanner-1.4.15/.github/workflows/fuzz.yml +53 -0
  12. plugin_scanner-1.4.15/.github/workflows/publish-action-repo.yml +169 -0
  13. plugin_scanner-1.4.15/.github/workflows/publish.yml +299 -0
  14. plugin_scanner-1.4.15/.github/workflows/scorecard.yml +27 -0
  15. plugin_scanner-1.4.15/.gitignore +42 -0
  16. plugin_scanner-1.4.15/.pre-commit-hooks.yaml +10 -0
  17. plugin_scanner-1.4.15/CONTRIBUTING.md +38 -0
  18. plugin_scanner-1.4.15/Dockerfile +51 -0
  19. plugin_scanner-1.4.15/LICENSE +120 -0
  20. plugin_scanner-1.4.15/PKG-INFO +596 -0
  21. plugin_scanner-1.4.15/README.md +561 -0
  22. plugin_scanner-1.4.15/SECURITY.md +34 -0
  23. plugin_scanner-1.4.15/action/README.md +268 -0
  24. plugin_scanner-1.4.15/action/action.yml +272 -0
  25. plugin_scanner-1.4.15/action/cisco-version.txt +1 -0
  26. plugin_scanner-1.4.15/action/pypi-attestations-version.txt +1 -0
  27. plugin_scanner-1.4.15/action/scanner-version.txt +1 -0
  28. plugin_scanner-1.4.15/docker-requirements.txt +12 -0
  29. plugin_scanner-1.4.15/docs/trust/mcp-trust-draft.md +41 -0
  30. plugin_scanner-1.4.15/docs/trust/plugin-trust-draft.md +56 -0
  31. plugin_scanner-1.4.15/docs/trust/skill-trust-local.md +60 -0
  32. plugin_scanner-1.4.15/fuzzers/manifest_fuzzer.py +19 -0
  33. plugin_scanner-1.4.15/pyproject.toml +74 -0
  34. plugin_scanner-1.4.15/schemas/plugin-quality.v1.json +140 -0
  35. plugin_scanner-1.4.15/schemas/scan-result.v1.json +393 -0
  36. plugin_scanner-1.4.15/schemas/verify-result.v1.json +81 -0
  37. plugin_scanner-1.4.15/src/codex_plugin_scanner/__init__.py +29 -0
  38. plugin_scanner-1.4.15/src/codex_plugin_scanner/action_runner.py +470 -0
  39. plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/__init__.py +0 -0
  40. plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/best_practices.py +238 -0
  41. plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/claude.py +285 -0
  42. plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/code_quality.py +115 -0
  43. plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/ecosystem_common.py +34 -0
  44. plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/gemini.py +196 -0
  45. plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/manifest.py +501 -0
  46. plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/manifest_support.py +61 -0
  47. plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/marketplace.py +334 -0
  48. plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/opencode.py +223 -0
  49. plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/operational_security.py +346 -0
  50. plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/security.py +447 -0
  51. plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/skill_security.py +241 -0
  52. plugin_scanner-1.4.15/src/codex_plugin_scanner/cli.py +467 -0
  53. plugin_scanner-1.4.15/src/codex_plugin_scanner/config.py +76 -0
  54. plugin_scanner-1.4.15/src/codex_plugin_scanner/ecosystems/__init__.py +15 -0
  55. plugin_scanner-1.4.15/src/codex_plugin_scanner/ecosystems/base.py +20 -0
  56. plugin_scanner-1.4.15/src/codex_plugin_scanner/ecosystems/claude.py +112 -0
  57. plugin_scanner-1.4.15/src/codex_plugin_scanner/ecosystems/codex.py +94 -0
  58. plugin_scanner-1.4.15/src/codex_plugin_scanner/ecosystems/detect.py +46 -0
  59. plugin_scanner-1.4.15/src/codex_plugin_scanner/ecosystems/gemini.py +80 -0
  60. plugin_scanner-1.4.15/src/codex_plugin_scanner/ecosystems/opencode.py +184 -0
  61. plugin_scanner-1.4.15/src/codex_plugin_scanner/ecosystems/registry.py +41 -0
  62. plugin_scanner-1.4.15/src/codex_plugin_scanner/ecosystems/types.py +45 -0
  63. plugin_scanner-1.4.15/src/codex_plugin_scanner/integrations/__init__.py +5 -0
  64. plugin_scanner-1.4.15/src/codex_plugin_scanner/integrations/cisco_skill_scanner.py +200 -0
  65. plugin_scanner-1.4.15/src/codex_plugin_scanner/lint_fixes.py +105 -0
  66. plugin_scanner-1.4.15/src/codex_plugin_scanner/marketplace_support.py +100 -0
  67. plugin_scanner-1.4.15/src/codex_plugin_scanner/models.py +177 -0
  68. plugin_scanner-1.4.15/src/codex_plugin_scanner/path_support.py +46 -0
  69. plugin_scanner-1.4.15/src/codex_plugin_scanner/policy.py +140 -0
  70. plugin_scanner-1.4.15/src/codex_plugin_scanner/quality_artifact.py +91 -0
  71. plugin_scanner-1.4.15/src/codex_plugin_scanner/repo_detect.py +137 -0
  72. plugin_scanner-1.4.15/src/codex_plugin_scanner/reporting.py +376 -0
  73. plugin_scanner-1.4.15/src/codex_plugin_scanner/rules/__init__.py +6 -0
  74. plugin_scanner-1.4.15/src/codex_plugin_scanner/rules/registry.py +101 -0
  75. plugin_scanner-1.4.15/src/codex_plugin_scanner/rules/specs.py +26 -0
  76. plugin_scanner-1.4.15/src/codex_plugin_scanner/scanner.py +557 -0
  77. plugin_scanner-1.4.15/src/codex_plugin_scanner/submission.py +284 -0
  78. plugin_scanner-1.4.15/src/codex_plugin_scanner/suppressions.py +87 -0
  79. plugin_scanner-1.4.15/src/codex_plugin_scanner/trust_domain_scoring.py +22 -0
  80. plugin_scanner-1.4.15/src/codex_plugin_scanner/trust_helpers.py +207 -0
  81. plugin_scanner-1.4.15/src/codex_plugin_scanner/trust_mcp_scoring.py +116 -0
  82. plugin_scanner-1.4.15/src/codex_plugin_scanner/trust_models.py +85 -0
  83. plugin_scanner-1.4.15/src/codex_plugin_scanner/trust_plugin_scoring.py +180 -0
  84. plugin_scanner-1.4.15/src/codex_plugin_scanner/trust_scoring.py +52 -0
  85. plugin_scanner-1.4.15/src/codex_plugin_scanner/trust_skill_scoring.py +296 -0
  86. plugin_scanner-1.4.15/src/codex_plugin_scanner/trust_specs.py +286 -0
  87. plugin_scanner-1.4.15/src/codex_plugin_scanner/verification.py +964 -0
  88. plugin_scanner-1.4.15/src/codex_plugin_scanner/version.py +3 -0
  89. plugin_scanner-1.4.15/tests/__init__.py +0 -0
  90. plugin_scanner-1.4.15/tests/fixtures/__init__.py +0 -0
  91. plugin_scanner-1.4.15/tests/fixtures/bad-plugin/.codex-plugin/plugin.json +1 -0
  92. plugin_scanner-1.4.15/tests/fixtures/bad-plugin/.mcp.json +1 -0
  93. plugin_scanner-1.4.15/tests/fixtures/bad-plugin/secrets.js +3 -0
  94. plugin_scanner-1.4.15/tests/fixtures/claude-plugin-good/.claude-plugin/plugin.json +6 -0
  95. plugin_scanner-1.4.15/tests/fixtures/claude-plugin-good/LICENSE +5 -0
  96. plugin_scanner-1.4.15/tests/fixtures/claude-plugin-good/README.md +3 -0
  97. plugin_scanner-1.4.15/tests/fixtures/claude-plugin-good/SECURITY.md +3 -0
  98. plugin_scanner-1.4.15/tests/fixtures/claude-plugin-good/hooks/hooks.json +5 -0
  99. plugin_scanner-1.4.15/tests/fixtures/claude-plugin-good/skills/example/SKILL.md +8 -0
  100. plugin_scanner-1.4.15/tests/fixtures/code-quality-bad/evil.js +4 -0
  101. plugin_scanner-1.4.15/tests/fixtures/code-quality-bad/inject.js +2 -0
  102. plugin_scanner-1.4.15/tests/fixtures/gemini-extension-good/GEMINI.md +3 -0
  103. plugin_scanner-1.4.15/tests/fixtures/gemini-extension-good/LICENSE +5 -0
  104. plugin_scanner-1.4.15/tests/fixtures/gemini-extension-good/README.md +3 -0
  105. plugin_scanner-1.4.15/tests/fixtures/gemini-extension-good/SECURITY.md +3 -0
  106. plugin_scanner-1.4.15/tests/fixtures/gemini-extension-good/commands/hello.toml +5 -0
  107. plugin_scanner-1.4.15/tests/fixtures/gemini-extension-good/gemini-extension.json +17 -0
  108. plugin_scanner-1.4.15/tests/fixtures/good-plugin/.codex-plugin/plugin.json +33 -0
  109. plugin_scanner-1.4.15/tests/fixtures/good-plugin/.codexignore +3 -0
  110. plugin_scanner-1.4.15/tests/fixtures/good-plugin/LICENSE +17 -0
  111. plugin_scanner-1.4.15/tests/fixtures/good-plugin/README.md +3 -0
  112. plugin_scanner-1.4.15/tests/fixtures/good-plugin/SECURITY.md +3 -0
  113. plugin_scanner-1.4.15/tests/fixtures/good-plugin/assets/icon.svg +4 -0
  114. plugin_scanner-1.4.15/tests/fixtures/good-plugin/assets/logo.svg +4 -0
  115. plugin_scanner-1.4.15/tests/fixtures/good-plugin/assets/screenshot.svg +6 -0
  116. plugin_scanner-1.4.15/tests/fixtures/good-plugin/skills/example/SKILL.md +15 -0
  117. plugin_scanner-1.4.15/tests/fixtures/malformed-json/.codex-plugin/plugin.json +1 -0
  118. plugin_scanner-1.4.15/tests/fixtures/minimal-plugin/.codex-plugin/plugin.json +1 -0
  119. plugin_scanner-1.4.15/tests/fixtures/missing-fields/.codex-plugin/plugin.json +1 -0
  120. plugin_scanner-1.4.15/tests/fixtures/mit-license/LICENSE +7 -0
  121. plugin_scanner-1.4.15/tests/fixtures/multi-ecosystem-repo/codex-plugin/.codex-plugin/plugin.json +5 -0
  122. plugin_scanner-1.4.15/tests/fixtures/multi-ecosystem-repo/codex-plugin/LICENSE +1 -0
  123. plugin_scanner-1.4.15/tests/fixtures/multi-ecosystem-repo/codex-plugin/README.md +1 -0
  124. plugin_scanner-1.4.15/tests/fixtures/multi-ecosystem-repo/codex-plugin/SECURITY.md +1 -0
  125. plugin_scanner-1.4.15/tests/fixtures/multi-ecosystem-repo/gemini-ext/README.md +1 -0
  126. plugin_scanner-1.4.15/tests/fixtures/multi-ecosystem-repo/gemini-ext/gemini-extension.json +5 -0
  127. plugin_scanner-1.4.15/tests/fixtures/multi-plugin-repo/.agents/plugins/marketplace.json +43 -0
  128. plugin_scanner-1.4.15/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codex-plugin/plugin.json +18 -0
  129. plugin_scanner-1.4.15/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codexignore +1 -0
  130. plugin_scanner-1.4.15/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/LICENSE +3 -0
  131. plugin_scanner-1.4.15/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/README.md +1 -0
  132. plugin_scanner-1.4.15/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/SECURITY.md +1 -0
  133. plugin_scanner-1.4.15/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/skills/example/SKILL.md +6 -0
  134. plugin_scanner-1.4.15/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/.codex-plugin/plugin.json +6 -0
  135. plugin_scanner-1.4.15/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/skills/example/SKILL.md +6 -0
  136. plugin_scanner-1.4.15/tests/fixtures/no-version/.codex-plugin/plugin.json +1 -0
  137. plugin_scanner-1.4.15/tests/fixtures/opencode-good/.opencode/commands/hello.md +6 -0
  138. plugin_scanner-1.4.15/tests/fixtures/opencode-good/.opencode/plugins/example.ts +5 -0
  139. plugin_scanner-1.4.15/tests/fixtures/opencode-good/LICENSE +5 -0
  140. plugin_scanner-1.4.15/tests/fixtures/opencode-good/README.md +3 -0
  141. plugin_scanner-1.4.15/tests/fixtures/opencode-good/SECURITY.md +3 -0
  142. plugin_scanner-1.4.15/tests/fixtures/opencode-good/opencode.jsonc +14 -0
  143. plugin_scanner-1.4.15/tests/fixtures/skills-missing-dir/.codex-plugin/plugin.json +1 -0
  144. plugin_scanner-1.4.15/tests/fixtures/skills-no-frontmatter/.codex-plugin/plugin.json +1 -0
  145. plugin_scanner-1.4.15/tests/fixtures/skills-no-frontmatter/skills/bad-skill/SKILL.md +1 -0
  146. plugin_scanner-1.4.15/tests/fixtures/with-marketplace/.codex-plugin/plugin.json +1 -0
  147. plugin_scanner-1.4.15/tests/fixtures/with-marketplace/marketplace-broken.json +8 -0
  148. plugin_scanner-1.4.15/tests/fixtures/with-marketplace/marketplace.json +20 -0
  149. plugin_scanner-1.4.15/tests/test-trust-scoring.py +173 -0
  150. plugin_scanner-1.4.15/tests/test-trust-specs.py +45 -0
  151. plugin_scanner-1.4.15/tests/test_action_bundle.py +239 -0
  152. plugin_scanner-1.4.15/tests/test_action_runner.py +217 -0
  153. plugin_scanner-1.4.15/tests/test_best_practices.py +109 -0
  154. plugin_scanner-1.4.15/tests/test_cli.py +380 -0
  155. plugin_scanner-1.4.15/tests/test_code_quality.py +79 -0
  156. plugin_scanner-1.4.15/tests/test_config.py +56 -0
  157. plugin_scanner-1.4.15/tests/test_coverage_remaining.py +146 -0
  158. plugin_scanner-1.4.15/tests/test_ecosystems.py +190 -0
  159. plugin_scanner-1.4.15/tests/test_edge_cases.py +153 -0
  160. plugin_scanner-1.4.15/tests/test_final_coverage.py +52 -0
  161. plugin_scanner-1.4.15/tests/test_integration.py +110 -0
  162. plugin_scanner-1.4.15/tests/test_lint_fixes.py +70 -0
  163. plugin_scanner-1.4.15/tests/test_live_cisco_smoke.py +32 -0
  164. plugin_scanner-1.4.15/tests/test_manifest.py +235 -0
  165. plugin_scanner-1.4.15/tests/test_marketplace.py +184 -0
  166. plugin_scanner-1.4.15/tests/test_operational_security.py +137 -0
  167. plugin_scanner-1.4.15/tests/test_policy.py +27 -0
  168. plugin_scanner-1.4.15/tests/test_quality_artifact.py +23 -0
  169. plugin_scanner-1.4.15/tests/test_rule_registry.py +17 -0
  170. plugin_scanner-1.4.15/tests/test_scanner.py +127 -0
  171. plugin_scanner-1.4.15/tests/test_schema_contracts.py +58 -0
  172. plugin_scanner-1.4.15/tests/test_security.py +193 -0
  173. plugin_scanner-1.4.15/tests/test_security_ops.py +50 -0
  174. plugin_scanner-1.4.15/tests/test_skill_security.py +171 -0
  175. plugin_scanner-1.4.15/tests/test_submission.py +221 -0
  176. plugin_scanner-1.4.15/tests/test_trust_scoring.py +235 -0
  177. plugin_scanner-1.4.15/tests/test_trust_specs.py +45 -0
  178. plugin_scanner-1.4.15/tests/test_verification.py +226 -0
  179. plugin_scanner-1.4.15/tests/test_versioning.py +14 -0
  180. plugin_scanner-1.4.15/uv.lock +3581 -0
@@ -0,0 +1,9 @@
1
+ FROM gcr.io/oss-fuzz-base/base-builder-python@sha256:721650302bfda2f3832df73bb24aeacfa41c32e692f3d6e4dd06074e79c64ed7
2
+
3
+ COPY ./.clusterfuzzlite/requirements-atheris.txt $SRC/requirements-atheris.txt
4
+ RUN python3 -m pip install --require-hashes --no-cache-dir --no-binary=:all: --no-deps \
5
+ -r $SRC/requirements-atheris.txt
6
+
7
+ COPY . $SRC/codex-plugin-scanner
8
+ WORKDIR $SRC/codex-plugin-scanner
9
+ COPY ./.clusterfuzzlite/build.sh $SRC/build.sh
@@ -0,0 +1,8 @@
1
+ #!/bin/bash -eu
2
+
3
+ cd "$SRC/codex-plugin-scanner"
4
+ export PYTHONPATH="$PWD/src${PYTHONPATH:+:$PYTHONPATH}"
5
+
6
+ for fuzzer in fuzzers/*_fuzzer.py; do
7
+ compile_python_fuzzer "$fuzzer"
8
+ done
@@ -0,0 +1,3 @@
1
+ homepage: "https://github.com/hashgraph-online/codex-plugin-scanner"
2
+ language: python
3
+ main_repo: "https://github.com/hashgraph-online/codex-plugin-scanner"
@@ -0,0 +1 @@
1
+ atheris==3.0.0 --hash=sha256:1f0929c7bc3040f3fe4102e557718734190cf2d7718bbb8e3ce6d3eb56ef5bb3
@@ -0,0 +1,10 @@
1
+ .git
2
+ .github
3
+ .pytest_cache
4
+ .ruff_cache
5
+ .venv
6
+ __pycache__
7
+ dist
8
+ tests
9
+ action
10
+ *.pyc
@@ -0,0 +1 @@
1
+ * @hashgraph-online/core
@@ -0,0 +1,12 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "github-actions"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ open-pull-requests-limit: 10
8
+ - package-ecosystem: "pip"
9
+ directory: "/"
10
+ schedule:
11
+ interval: "weekly"
12
+ open-pull-requests-limit: 10
@@ -0,0 +1,45 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ pull_request:
6
+ branches: [main]
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ ci:
13
+ runs-on: ubuntu-latest
14
+ strategy:
15
+ matrix:
16
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
17
+ steps:
18
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
19
+ - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
20
+ with:
21
+ python-version: ${{ matrix.python-version }}
22
+ - uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e
23
+ with:
24
+ enable-cache: true
25
+ - run: uv sync --frozen --extra dev --python ${{ matrix.python-version }}
26
+ - run: uv run --no-sync python -m ruff check src/
27
+ - run: uv run --no-sync python -m ruff format --check src/
28
+ - run: uv run --no-sync pytest --tb=short
29
+
30
+ cross-platform:
31
+ runs-on: ${{ matrix.os }}
32
+ strategy:
33
+ matrix:
34
+ os: [macos-latest, windows-latest]
35
+ python-version: ["3.12"]
36
+ steps:
37
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
38
+ - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
39
+ with:
40
+ python-version: ${{ matrix.python-version }}
41
+ - uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e
42
+ with:
43
+ enable-cache: true
44
+ - run: uv sync --frozen --extra dev --python ${{ matrix.python-version }}
45
+ - run: uv run --no-sync pytest tests/test_cli.py tests/test_verification.py tests/test_action_runner.py --tb=short
@@ -0,0 +1,41 @@
1
+ name: CodeQL
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+ schedule:
9
+ - cron: "0 4 * * 1"
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ jobs:
15
+ analyze:
16
+ name: Analyze (${{ matrix.language }})
17
+ if: ${{ vars.CODEQL_ADVANCED_ENABLED == 'true' }}
18
+ runs-on: ubuntu-latest
19
+ strategy:
20
+ fail-fast: false
21
+ matrix:
22
+ language: [actions, python]
23
+ permissions:
24
+ actions: read
25
+ contents: read
26
+ security-events: write
27
+ steps:
28
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
29
+ - name: Provide legacy workspace alias for CodeQL default setup state
30
+ run: |
31
+ LEGACY_ROOT="/home/runner/work/codex-plugin-scanner"
32
+ mkdir -p "$LEGACY_ROOT"
33
+ ln -sfn "$GITHUB_WORKSPACE" "$LEGACY_ROOT/codex-plugin-scanner"
34
+ - uses: github/codeql-action/init@51f77329afa6477de8c49fc9c7046c15b9a4e79d
35
+ with:
36
+ languages: ${{ matrix.language }}
37
+ build-mode: none
38
+ source-root: .
39
+ - uses: github/codeql-action/analyze@51f77329afa6477de8c49fc9c7046c15b9a4e79d
40
+ with:
41
+ category: /language:${{ matrix.language }}
@@ -0,0 +1,112 @@
1
+ name: E2E Tests
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+ push:
7
+ branches: [feat/*]
8
+ workflow_dispatch:
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ jobs:
14
+ scanner-text:
15
+ name: Scanner (text format)
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
19
+ - uses: ./action
20
+ id: scan
21
+ with:
22
+ install_source: local
23
+ plugin_dir: tests/fixtures/good-plugin
24
+ min_score: 80
25
+
26
+ scanner-json:
27
+ name: Scanner (JSON format)
28
+ runs-on: ubuntu-latest
29
+ steps:
30
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
31
+ - uses: ./action
32
+ id: scan
33
+ with:
34
+ install_source: local
35
+ plugin_dir: tests/fixtures/good-plugin
36
+ format: json
37
+ output: report.json
38
+ - name: Validate JSON
39
+ run: |
40
+ python3 -c "
41
+ import json
42
+ d = json.load(open('report.json'))
43
+ assert 'score' in d
44
+ assert 'grade' in d
45
+ assert d['score'] >= 80, f'Expected score >= 80, got {d[\"score\"]}'
46
+ print(f'JSON output valid: score={d[\"score\"]}, grade={d[\"grade\"]}')
47
+ "
48
+
49
+ scanner-sarif:
50
+ name: Scanner (SARIF format)
51
+ runs-on: ubuntu-latest
52
+ steps:
53
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
54
+ - uses: ./action
55
+ id: scan
56
+ with:
57
+ install_source: local
58
+ plugin_dir: tests/fixtures/good-plugin
59
+ format: sarif
60
+ output: report.sarif
61
+ - name: Validate SARIF
62
+ run: |
63
+ python3 -c "
64
+ import json
65
+ d = json.load(open('report.sarif'))
66
+ assert d['version'] == '2.1.0'
67
+ assert d['\$schema'].startswith('https://')
68
+ print('SARIF output valid')
69
+ "
70
+ # Skip SARIF upload - CodeQL upload-sarif requires code scanning to be enabled on the repo
71
+
72
+ scanner-fail:
73
+ name: Scanner (fail on low score)
74
+ runs-on: ubuntu-latest
75
+ steps:
76
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
77
+ - uses: ./action
78
+ id: scan
79
+ continue-on-error: true
80
+ with:
81
+ install_source: local
82
+ plugin_dir: tests/fixtures/bad-plugin
83
+ min_score: 99
84
+ - name: Verify failure
85
+ if: always() && steps.scan.outcome == 'failure'
86
+ run: echo "Correctly failed for low score"
87
+ - name: Should have failed
88
+ if: always() && steps.scan.outcome != 'failure'
89
+ run: |
90
+ echo "Expected failure but scanner passed"
91
+ exit 1
92
+
93
+ scanner-markdown:
94
+ name: Scanner (Markdown format)
95
+ runs-on: ubuntu-latest
96
+ steps:
97
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
98
+ - uses: ./action
99
+ id: scan
100
+ with:
101
+ install_source: local
102
+ plugin_dir: tests/fixtures/good-plugin
103
+ format: markdown
104
+ output: report.md
105
+ - name: Validate Markdown
106
+ run: |
107
+ python3 -c "
108
+ content = open('report.md').read()
109
+ assert '/100' in content
110
+ assert 'Excellent' in content or 'Good' in content or 'Fair' in content
111
+ print('Markdown output valid')
112
+ "
@@ -0,0 +1,53 @@
1
+ name: Fuzzing
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+ push:
7
+ branches: [main]
8
+ schedule:
9
+ - cron: "0 6 * * 1"
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ jobs:
15
+ code-change:
16
+ if: github.event_name == 'pull_request'
17
+ runs-on: ubuntu-latest
18
+ permissions:
19
+ contents: read
20
+ security-events: write
21
+ steps:
22
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
23
+ - uses: google/clusterfuzzlite/actions/build_fuzzers@52ecc61cb587ee99c26825a112a21abf19c7448c
24
+ with:
25
+ language: python
26
+ sanitizer: address
27
+ - uses: google/clusterfuzzlite/actions/run_fuzzers@52ecc61cb587ee99c26825a112a21abf19c7448c
28
+ with:
29
+ github-token: ${{ secrets.GITHUB_TOKEN }}
30
+ mode: code-change
31
+ sanitizer: address
32
+ fuzz-seconds: 600
33
+ output-sarif: true
34
+
35
+ batch:
36
+ if: github.event_name != 'pull_request'
37
+ runs-on: ubuntu-latest
38
+ permissions:
39
+ contents: read
40
+ security-events: write
41
+ steps:
42
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
43
+ - uses: google/clusterfuzzlite/actions/build_fuzzers@52ecc61cb587ee99c26825a112a21abf19c7448c
44
+ with:
45
+ language: python
46
+ sanitizer: address
47
+ - uses: google/clusterfuzzlite/actions/run_fuzzers@52ecc61cb587ee99c26825a112a21abf19c7448c
48
+ with:
49
+ github-token: ${{ secrets.GITHUB_TOKEN }}
50
+ mode: batch
51
+ sanitizer: address
52
+ fuzz-seconds: 1800
53
+ output-sarif: true
@@ -0,0 +1,169 @@
1
+ name: Publish GitHub Action Repository
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ branches:
7
+ - main
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ concurrency:
13
+ group: codex-plugin-scanner-action-repo-${{ github.ref }}
14
+ cancel-in-progress: false
15
+
16
+ jobs:
17
+ publish-action-repo:
18
+ name: Sync action repo + publish release notes
19
+ runs-on: ubuntu-latest
20
+ permissions:
21
+ contents: read
22
+ env:
23
+ ACTION_REPOSITORY: ${{ vars.ACTION_REPOSITORY != '' && vars.ACTION_REPOSITORY || 'hashgraph-online/hol-codex-plugin-scanner-action' }}
24
+ SOURCE_REF: ${{ github.sha }}
25
+ SOURCE_REPOSITORY: ${{ github.repository }}
26
+ SOURCE_SERVER_URL: ${{ github.server_url }}
27
+ steps:
28
+ - name: Validate publication credentials
29
+ env:
30
+ ACTION_REPO_TOKEN: ${{ secrets.ACTION_REPO_TOKEN }}
31
+ run: |
32
+ if [ -z "$ACTION_REPO_TOKEN" ]; then
33
+ echo "ACTION_REPO_TOKEN must be configured to publish the Marketplace action repository." >&2
34
+ exit 1
35
+ fi
36
+
37
+ - name: Checkout source repository
38
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
39
+ with:
40
+ fetch-depth: 0
41
+
42
+ - name: Compute next action release tag
43
+ id: version
44
+ env:
45
+ GH_TOKEN: ${{ secrets.ACTION_REPO_TOKEN }}
46
+ run: |
47
+ LAST_TAG=$(gh release list --repo "$ACTION_REPOSITORY" --limit 1 --json tagName --jq '.[0].tagName // ""')
48
+
49
+ if [ -z "$LAST_TAG" ]; then
50
+ TAG="v1.0.0"
51
+ else
52
+ IFS=. read -r MAJOR MINOR PATCH <<< "${LAST_TAG#v}"
53
+ if [ -z "$MAJOR" ] || [ -z "$MINOR" ] || [ -z "$PATCH" ]; then
54
+ echo "Unsupported release tag format: $LAST_TAG" >&2
55
+ exit 1
56
+ fi
57
+ TAG="v${MAJOR}.${MINOR}.$((PATCH + 1))"
58
+ fi
59
+
60
+ echo "tag=$TAG" >> "$GITHUB_OUTPUT"
61
+
62
+ - name: Compute scanner package version
63
+ id: scanner_version
64
+ env:
65
+ GITHUB_REF: ${{ github.ref }}
66
+ GITHUB_EVENT_NAME: ${{ github.event_name }}
67
+ run: |
68
+ BASE_VERSION=$(python3 -c "import tomllib; p=tomllib.load(open('pyproject.toml','rb')); print(p['project']['version'])")
69
+ VERSION="$BASE_VERSION"
70
+ if [[ "$GITHUB_REF" == refs/tags/v* ]]; then
71
+ VERSION="${GITHUB_REF#refs/tags/v}"
72
+ elif [[ "$GITHUB_EVENT_NAME" == "push" && "$GITHUB_REF" == "refs/heads/main" ]]; then
73
+ LAST_TAG=$(git tag --list 'v*' --sort=-version:refname | head -n1)
74
+ if [[ -n "$LAST_TAG" ]]; then
75
+ IFS=. read -r MAJOR MINOR PATCH <<< "${LAST_TAG#v}"
76
+ if [[ -z "$MAJOR" || -z "$MINOR" || -z "$PATCH" ]]; then
77
+ echo "Unsupported release tag format: $LAST_TAG" >&2
78
+ exit 1
79
+ fi
80
+ VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))"
81
+ fi
82
+ fi
83
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
84
+
85
+ - name: Clone action repository
86
+ env:
87
+ GH_TOKEN: ${{ secrets.ACTION_REPO_TOKEN }}
88
+ run: gh repo clone "$ACTION_REPOSITORY" action-repo -- --depth 1
89
+
90
+ - name: Configure authenticated action repository remote
91
+ working-directory: action-repo
92
+ env:
93
+ ACTION_REPO_TOKEN: ${{ secrets.ACTION_REPO_TOKEN }}
94
+ run: |
95
+ git remote set-url origin "https://x-access-token:${ACTION_REPO_TOKEN}@github.com/$ACTION_REPOSITORY.git"
96
+
97
+ - name: Sync root-ready action bundle
98
+ working-directory: action-repo
99
+ run: |
100
+ cp "${GITHUB_WORKSPACE}/action/action.yml" action.yml
101
+ cp "${GITHUB_WORKSPACE}/action/README.md" README.md
102
+ printf '%s\n' "${{ steps.scanner_version.outputs.version }}" > scanner-version.txt
103
+ cp "${GITHUB_WORKSPACE}/action/cisco-version.txt" cisco-version.txt
104
+ cp "${GITHUB_WORKSPACE}/action/pypi-attestations-version.txt" pypi-attestations-version.txt
105
+ cp "${GITHUB_WORKSPACE}/LICENSE" LICENSE
106
+ cp "${GITHUB_WORKSPACE}/SECURITY.md" SECURITY.md
107
+ cp "${GITHUB_WORKSPACE}/CONTRIBUTING.md" CONTRIBUTING.md
108
+
109
+ - name: Detect sync changes
110
+ id: diff
111
+ working-directory: action-repo
112
+ run: |
113
+ if [ -n "$(git status --short -- action.yml README.md scanner-version.txt cisco-version.txt pypi-attestations-version.txt LICENSE SECURITY.md CONTRIBUTING.md)" ]; then
114
+ echo "changed=true" >> "$GITHUB_OUTPUT"
115
+ else
116
+ echo "changed=false" >> "$GITHUB_OUTPUT"
117
+ fi
118
+
119
+ - name: Commit synced bundle
120
+ if: steps.diff.outputs.changed == 'true'
121
+ working-directory: action-repo
122
+ run: |
123
+ git config user.name "github-actions[bot]"
124
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
125
+ git add action.yml README.md scanner-version.txt cisco-version.txt pypi-attestations-version.txt LICENSE SECURITY.md CONTRIBUTING.md
126
+ git commit -m "chore: publish action bundle ${{ steps.version.outputs.tag }}"
127
+
128
+ - name: Push action repository branch and tags
129
+ if: steps.diff.outputs.changed == 'true'
130
+ working-directory: action-repo
131
+ run: |
132
+ TAG="${{ steps.version.outputs.tag }}"
133
+ git push origin HEAD:main
134
+ git tag "$TAG"
135
+ git push origin "refs/tags/${TAG}"
136
+ git tag -fa v1 -m "Update floating major tag to ${TAG}"
137
+ git push origin refs/tags/v1 --force
138
+
139
+ - name: Check action release state
140
+ id: release_state
141
+ working-directory: action-repo
142
+ env:
143
+ GH_TOKEN: ${{ secrets.ACTION_REPO_TOKEN }}
144
+ run: |
145
+ TAG="${{ steps.version.outputs.tag }}"
146
+
147
+ if gh release view "${TAG}" --repo "$ACTION_REPOSITORY" >/dev/null 2>&1; then
148
+ echo "release_exists=true" >> "$GITHUB_OUTPUT"
149
+ else
150
+ echo "release_exists=false" >> "$GITHUB_OUTPUT"
151
+ fi
152
+
153
+ if git ls-remote --tags origin "refs/tags/${TAG}" | grep -q .; then
154
+ echo "tag_exists=true" >> "$GITHUB_OUTPUT"
155
+ else
156
+ echo "tag_exists=false" >> "$GITHUB_OUTPUT"
157
+ fi
158
+
159
+ - name: Create action repository release
160
+ if: steps.release_state.outputs.release_exists == 'false' && (steps.diff.outputs.changed == 'true' || steps.release_state.outputs.tag_exists == 'true')
161
+ env:
162
+ GH_TOKEN: ${{ secrets.ACTION_REPO_TOKEN }}
163
+ run: |
164
+ TAG="${{ steps.version.outputs.tag }}"
165
+ gh release create "${TAG}" \
166
+ --repo "$ACTION_REPOSITORY" \
167
+ --title "$TAG" \
168
+ --generate-notes \
169
+ --notes "Published automatically from ${SOURCE_SERVER_URL}/${SOURCE_REPOSITORY}/tree/${SOURCE_REF}"