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.
- plugin_scanner-1.4.15/.clusterfuzzlite/Dockerfile +9 -0
- plugin_scanner-1.4.15/.clusterfuzzlite/build.sh +8 -0
- plugin_scanner-1.4.15/.clusterfuzzlite/project.yaml +3 -0
- plugin_scanner-1.4.15/.clusterfuzzlite/requirements-atheris.txt +1 -0
- plugin_scanner-1.4.15/.dockerignore +10 -0
- plugin_scanner-1.4.15/.github/CODEOWNERS +1 -0
- plugin_scanner-1.4.15/.github/dependabot.yml +12 -0
- plugin_scanner-1.4.15/.github/workflows/ci.yml +45 -0
- plugin_scanner-1.4.15/.github/workflows/codeql.yml +41 -0
- plugin_scanner-1.4.15/.github/workflows/e2e-test.yml +112 -0
- plugin_scanner-1.4.15/.github/workflows/fuzz.yml +53 -0
- plugin_scanner-1.4.15/.github/workflows/publish-action-repo.yml +169 -0
- plugin_scanner-1.4.15/.github/workflows/publish.yml +299 -0
- plugin_scanner-1.4.15/.github/workflows/scorecard.yml +27 -0
- plugin_scanner-1.4.15/.gitignore +42 -0
- plugin_scanner-1.4.15/.pre-commit-hooks.yaml +10 -0
- plugin_scanner-1.4.15/CONTRIBUTING.md +38 -0
- plugin_scanner-1.4.15/Dockerfile +51 -0
- plugin_scanner-1.4.15/LICENSE +120 -0
- plugin_scanner-1.4.15/PKG-INFO +596 -0
- plugin_scanner-1.4.15/README.md +561 -0
- plugin_scanner-1.4.15/SECURITY.md +34 -0
- plugin_scanner-1.4.15/action/README.md +268 -0
- plugin_scanner-1.4.15/action/action.yml +272 -0
- plugin_scanner-1.4.15/action/cisco-version.txt +1 -0
- plugin_scanner-1.4.15/action/pypi-attestations-version.txt +1 -0
- plugin_scanner-1.4.15/action/scanner-version.txt +1 -0
- plugin_scanner-1.4.15/docker-requirements.txt +12 -0
- plugin_scanner-1.4.15/docs/trust/mcp-trust-draft.md +41 -0
- plugin_scanner-1.4.15/docs/trust/plugin-trust-draft.md +56 -0
- plugin_scanner-1.4.15/docs/trust/skill-trust-local.md +60 -0
- plugin_scanner-1.4.15/fuzzers/manifest_fuzzer.py +19 -0
- plugin_scanner-1.4.15/pyproject.toml +74 -0
- plugin_scanner-1.4.15/schemas/plugin-quality.v1.json +140 -0
- plugin_scanner-1.4.15/schemas/scan-result.v1.json +393 -0
- plugin_scanner-1.4.15/schemas/verify-result.v1.json +81 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/__init__.py +29 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/action_runner.py +470 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/__init__.py +0 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/best_practices.py +238 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/claude.py +285 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/code_quality.py +115 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/ecosystem_common.py +34 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/gemini.py +196 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/manifest.py +501 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/manifest_support.py +61 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/marketplace.py +334 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/opencode.py +223 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/operational_security.py +346 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/security.py +447 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/checks/skill_security.py +241 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/cli.py +467 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/config.py +76 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/ecosystems/__init__.py +15 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/ecosystems/base.py +20 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/ecosystems/claude.py +112 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/ecosystems/codex.py +94 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/ecosystems/detect.py +46 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/ecosystems/gemini.py +80 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/ecosystems/opencode.py +184 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/ecosystems/registry.py +41 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/ecosystems/types.py +45 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/integrations/__init__.py +5 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/integrations/cisco_skill_scanner.py +200 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/lint_fixes.py +105 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/marketplace_support.py +100 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/models.py +177 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/path_support.py +46 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/policy.py +140 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/quality_artifact.py +91 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/repo_detect.py +137 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/reporting.py +376 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/rules/__init__.py +6 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/rules/registry.py +101 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/rules/specs.py +26 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/scanner.py +557 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/submission.py +284 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/suppressions.py +87 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/trust_domain_scoring.py +22 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/trust_helpers.py +207 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/trust_mcp_scoring.py +116 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/trust_models.py +85 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/trust_plugin_scoring.py +180 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/trust_scoring.py +52 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/trust_skill_scoring.py +296 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/trust_specs.py +286 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/verification.py +964 -0
- plugin_scanner-1.4.15/src/codex_plugin_scanner/version.py +3 -0
- plugin_scanner-1.4.15/tests/__init__.py +0 -0
- plugin_scanner-1.4.15/tests/fixtures/__init__.py +0 -0
- plugin_scanner-1.4.15/tests/fixtures/bad-plugin/.codex-plugin/plugin.json +1 -0
- plugin_scanner-1.4.15/tests/fixtures/bad-plugin/.mcp.json +1 -0
- plugin_scanner-1.4.15/tests/fixtures/bad-plugin/secrets.js +3 -0
- plugin_scanner-1.4.15/tests/fixtures/claude-plugin-good/.claude-plugin/plugin.json +6 -0
- plugin_scanner-1.4.15/tests/fixtures/claude-plugin-good/LICENSE +5 -0
- plugin_scanner-1.4.15/tests/fixtures/claude-plugin-good/README.md +3 -0
- plugin_scanner-1.4.15/tests/fixtures/claude-plugin-good/SECURITY.md +3 -0
- plugin_scanner-1.4.15/tests/fixtures/claude-plugin-good/hooks/hooks.json +5 -0
- plugin_scanner-1.4.15/tests/fixtures/claude-plugin-good/skills/example/SKILL.md +8 -0
- plugin_scanner-1.4.15/tests/fixtures/code-quality-bad/evil.js +4 -0
- plugin_scanner-1.4.15/tests/fixtures/code-quality-bad/inject.js +2 -0
- plugin_scanner-1.4.15/tests/fixtures/gemini-extension-good/GEMINI.md +3 -0
- plugin_scanner-1.4.15/tests/fixtures/gemini-extension-good/LICENSE +5 -0
- plugin_scanner-1.4.15/tests/fixtures/gemini-extension-good/README.md +3 -0
- plugin_scanner-1.4.15/tests/fixtures/gemini-extension-good/SECURITY.md +3 -0
- plugin_scanner-1.4.15/tests/fixtures/gemini-extension-good/commands/hello.toml +5 -0
- plugin_scanner-1.4.15/tests/fixtures/gemini-extension-good/gemini-extension.json +17 -0
- plugin_scanner-1.4.15/tests/fixtures/good-plugin/.codex-plugin/plugin.json +33 -0
- plugin_scanner-1.4.15/tests/fixtures/good-plugin/.codexignore +3 -0
- plugin_scanner-1.4.15/tests/fixtures/good-plugin/LICENSE +17 -0
- plugin_scanner-1.4.15/tests/fixtures/good-plugin/README.md +3 -0
- plugin_scanner-1.4.15/tests/fixtures/good-plugin/SECURITY.md +3 -0
- plugin_scanner-1.4.15/tests/fixtures/good-plugin/assets/icon.svg +4 -0
- plugin_scanner-1.4.15/tests/fixtures/good-plugin/assets/logo.svg +4 -0
- plugin_scanner-1.4.15/tests/fixtures/good-plugin/assets/screenshot.svg +6 -0
- plugin_scanner-1.4.15/tests/fixtures/good-plugin/skills/example/SKILL.md +15 -0
- plugin_scanner-1.4.15/tests/fixtures/malformed-json/.codex-plugin/plugin.json +1 -0
- plugin_scanner-1.4.15/tests/fixtures/minimal-plugin/.codex-plugin/plugin.json +1 -0
- plugin_scanner-1.4.15/tests/fixtures/missing-fields/.codex-plugin/plugin.json +1 -0
- plugin_scanner-1.4.15/tests/fixtures/mit-license/LICENSE +7 -0
- plugin_scanner-1.4.15/tests/fixtures/multi-ecosystem-repo/codex-plugin/.codex-plugin/plugin.json +5 -0
- plugin_scanner-1.4.15/tests/fixtures/multi-ecosystem-repo/codex-plugin/LICENSE +1 -0
- plugin_scanner-1.4.15/tests/fixtures/multi-ecosystem-repo/codex-plugin/README.md +1 -0
- plugin_scanner-1.4.15/tests/fixtures/multi-ecosystem-repo/codex-plugin/SECURITY.md +1 -0
- plugin_scanner-1.4.15/tests/fixtures/multi-ecosystem-repo/gemini-ext/README.md +1 -0
- plugin_scanner-1.4.15/tests/fixtures/multi-ecosystem-repo/gemini-ext/gemini-extension.json +5 -0
- plugin_scanner-1.4.15/tests/fixtures/multi-plugin-repo/.agents/plugins/marketplace.json +43 -0
- plugin_scanner-1.4.15/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codex-plugin/plugin.json +18 -0
- plugin_scanner-1.4.15/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codexignore +1 -0
- plugin_scanner-1.4.15/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/LICENSE +3 -0
- plugin_scanner-1.4.15/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/README.md +1 -0
- plugin_scanner-1.4.15/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/SECURITY.md +1 -0
- plugin_scanner-1.4.15/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/skills/example/SKILL.md +6 -0
- plugin_scanner-1.4.15/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/.codex-plugin/plugin.json +6 -0
- plugin_scanner-1.4.15/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/skills/example/SKILL.md +6 -0
- plugin_scanner-1.4.15/tests/fixtures/no-version/.codex-plugin/plugin.json +1 -0
- plugin_scanner-1.4.15/tests/fixtures/opencode-good/.opencode/commands/hello.md +6 -0
- plugin_scanner-1.4.15/tests/fixtures/opencode-good/.opencode/plugins/example.ts +5 -0
- plugin_scanner-1.4.15/tests/fixtures/opencode-good/LICENSE +5 -0
- plugin_scanner-1.4.15/tests/fixtures/opencode-good/README.md +3 -0
- plugin_scanner-1.4.15/tests/fixtures/opencode-good/SECURITY.md +3 -0
- plugin_scanner-1.4.15/tests/fixtures/opencode-good/opencode.jsonc +14 -0
- plugin_scanner-1.4.15/tests/fixtures/skills-missing-dir/.codex-plugin/plugin.json +1 -0
- plugin_scanner-1.4.15/tests/fixtures/skills-no-frontmatter/.codex-plugin/plugin.json +1 -0
- plugin_scanner-1.4.15/tests/fixtures/skills-no-frontmatter/skills/bad-skill/SKILL.md +1 -0
- plugin_scanner-1.4.15/tests/fixtures/with-marketplace/.codex-plugin/plugin.json +1 -0
- plugin_scanner-1.4.15/tests/fixtures/with-marketplace/marketplace-broken.json +8 -0
- plugin_scanner-1.4.15/tests/fixtures/with-marketplace/marketplace.json +20 -0
- plugin_scanner-1.4.15/tests/test-trust-scoring.py +173 -0
- plugin_scanner-1.4.15/tests/test-trust-specs.py +45 -0
- plugin_scanner-1.4.15/tests/test_action_bundle.py +239 -0
- plugin_scanner-1.4.15/tests/test_action_runner.py +217 -0
- plugin_scanner-1.4.15/tests/test_best_practices.py +109 -0
- plugin_scanner-1.4.15/tests/test_cli.py +380 -0
- plugin_scanner-1.4.15/tests/test_code_quality.py +79 -0
- plugin_scanner-1.4.15/tests/test_config.py +56 -0
- plugin_scanner-1.4.15/tests/test_coverage_remaining.py +146 -0
- plugin_scanner-1.4.15/tests/test_ecosystems.py +190 -0
- plugin_scanner-1.4.15/tests/test_edge_cases.py +153 -0
- plugin_scanner-1.4.15/tests/test_final_coverage.py +52 -0
- plugin_scanner-1.4.15/tests/test_integration.py +110 -0
- plugin_scanner-1.4.15/tests/test_lint_fixes.py +70 -0
- plugin_scanner-1.4.15/tests/test_live_cisco_smoke.py +32 -0
- plugin_scanner-1.4.15/tests/test_manifest.py +235 -0
- plugin_scanner-1.4.15/tests/test_marketplace.py +184 -0
- plugin_scanner-1.4.15/tests/test_operational_security.py +137 -0
- plugin_scanner-1.4.15/tests/test_policy.py +27 -0
- plugin_scanner-1.4.15/tests/test_quality_artifact.py +23 -0
- plugin_scanner-1.4.15/tests/test_rule_registry.py +17 -0
- plugin_scanner-1.4.15/tests/test_scanner.py +127 -0
- plugin_scanner-1.4.15/tests/test_schema_contracts.py +58 -0
- plugin_scanner-1.4.15/tests/test_security.py +193 -0
- plugin_scanner-1.4.15/tests/test_security_ops.py +50 -0
- plugin_scanner-1.4.15/tests/test_skill_security.py +171 -0
- plugin_scanner-1.4.15/tests/test_submission.py +221 -0
- plugin_scanner-1.4.15/tests/test_trust_scoring.py +235 -0
- plugin_scanner-1.4.15/tests/test_trust_specs.py +45 -0
- plugin_scanner-1.4.15/tests/test_verification.py +226 -0
- plugin_scanner-1.4.15/tests/test_versioning.py +14 -0
- 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 @@
|
|
|
1
|
+
atheris==3.0.0 --hash=sha256:1f0929c7bc3040f3fe4102e557718734190cf2d7718bbb8e3ce6d3eb56ef5bb3
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* @hashgraph-online/core
|
|
@@ -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}"
|