|
1 | 1 | # CodeClone GitHub Action |
2 | 2 |
|
3 | | -Runs CodeClone to detect architectural code duplication in Python projects. |
| 3 | +Baseline-aware structural code quality analysis for Python with: |
4 | 4 |
|
5 | | -## Usage |
| 5 | +- configurable CI gating |
| 6 | +- SARIF upload for GitHub Code Scanning |
| 7 | +- PR summary comments |
| 8 | +- deterministic JSON report generation |
| 9 | + |
| 10 | +This action is designed for PR and CI workflows where you want CodeClone to act |
| 11 | +as a non-LLM review bot: run analysis, upload SARIF, post a concise summary, |
| 12 | +and propagate the real gate result. |
| 13 | + |
| 14 | +## What it does |
| 15 | + |
| 16 | +The v2 action flow is: |
| 17 | + |
| 18 | +1. set up Python |
| 19 | +2. install `codeclone` from PyPI |
| 20 | +3. optionally require a committed baseline |
| 21 | +4. run CodeClone with JSON + optional SARIF output |
| 22 | +5. optionally upload SARIF to GitHub Code Scanning |
| 23 | +6. optionally post or update a PR summary comment |
| 24 | +7. return the real CodeClone exit code as the job result |
| 25 | + |
| 26 | +## Basic usage |
6 | 27 |
|
7 | 28 | ```yaml |
8 | | -- uses: orenlab/codeclone/.github/actions/codeclone@v1 |
| 29 | +- uses: orenlab/codeclone/.github/actions/codeclone@main |
9 | 30 | with: |
10 | | - path: . |
11 | | - fail-on-new: true |
| 31 | + fail-on-new: "true" |
| 32 | +``` |
| 33 | +
|
| 34 | +For released references, prefer pinning to a major version tag such as `@v2` |
| 35 | +or to an immutable commit SHA. |
| 36 | + |
| 37 | +## PR workflow example |
| 38 | + |
| 39 | +```yaml |
| 40 | +name: CodeClone |
| 41 | +
|
| 42 | +on: |
| 43 | + pull_request: |
| 44 | + types: [opened, synchronize, reopened] |
| 45 | + paths: ["**/*.py"] |
| 46 | +
|
| 47 | +permissions: |
| 48 | + contents: read |
| 49 | + security-events: write |
| 50 | + pull-requests: write |
| 51 | +
|
| 52 | +jobs: |
| 53 | + codeclone: |
| 54 | + runs-on: ubuntu-latest |
| 55 | + steps: |
| 56 | + - uses: actions/checkout@v4 |
| 57 | + with: |
| 58 | + fetch-depth: 0 |
| 59 | +
|
| 60 | + - uses: orenlab/codeclone/.github/actions/codeclone@main |
| 61 | + with: |
| 62 | + fail-on-new: "true" |
| 63 | + fail-health: "60" |
| 64 | + sarif: "true" |
| 65 | + pr-comment: "true" |
| 66 | +``` |
| 67 | + |
| 68 | +## Inputs |
| 69 | + |
| 70 | +| Input | Default | Purpose | |
| 71 | +|-------|---------|---------| |
| 72 | +| `python-version` | `3.13` | Python version used to run the action | |
| 73 | +| `package-version` | `""` | CodeClone version from PyPI; empty means latest stable | |
| 74 | +| `path` | `.` | Project root to analyze | |
| 75 | +| `json-path` | `.cache/codeclone/report.json` | JSON report output path | |
| 76 | +| `sarif` | `true` | Generate SARIF and try to upload it | |
| 77 | +| `sarif-path` | `.cache/codeclone/report.sarif` | SARIF output path | |
| 78 | +| `pr-comment` | `true` | Post or update a PR summary comment | |
| 79 | +| `fail-on-new` | `true` | Fail if new clone groups are detected | |
| 80 | +| `fail-on-new-metrics` | `false` | Fail if metrics regress vs baseline | |
| 81 | +| `fail-threshold` | `-1` | Max allowed function+block clone groups | |
| 82 | +| `fail-complexity` | `-1` | Max cyclomatic complexity | |
| 83 | +| `fail-coupling` | `-1` | Max coupling CBO | |
| 84 | +| `fail-cohesion` | `-1` | Max cohesion LCOM4 | |
| 85 | +| `fail-cycles` | `false` | Fail on dependency cycles | |
| 86 | +| `fail-dead-code` | `false` | Fail on high-confidence dead code | |
| 87 | +| `fail-health` | `-1` | Minimum health score | |
| 88 | +| `require-baseline` | `true` | Fail early if the baseline file is missing | |
| 89 | +| `baseline-path` | `codeclone.baseline.json` | Baseline path passed to CodeClone | |
| 90 | +| `metrics-baseline-path` | `codeclone.baseline.json` | Metrics baseline path passed to CodeClone | |
| 91 | +| `extra-args` | `""` | Additional CodeClone CLI arguments | |
| 92 | +| `no-progress` | `true` | Disable progress output | |
| 93 | + |
| 94 | +For numeric gate inputs, `-1` means "disabled". |
| 95 | + |
| 96 | +## Outputs |
| 97 | + |
| 98 | +| Output | Meaning | |
| 99 | +|--------|---------| |
| 100 | +| `exit-code` | CodeClone process exit code | |
| 101 | +| `json-path` | Resolved JSON report path | |
| 102 | +| `sarif-path` | Resolved SARIF report path | |
| 103 | +| `pr-comment-id` | PR comment id when the action updated or created a comment | |
| 104 | + |
| 105 | +## Exit behavior |
| 106 | + |
| 107 | +The action propagates the real CodeClone exit code at the end: |
| 108 | + |
| 109 | +- `0` — success |
| 110 | +- `2` — contract error |
| 111 | +- `3` — gating failure |
| 112 | +- `5` — internal error |
| 113 | + |
| 114 | +SARIF upload and PR comment posting are treated as additive integrations. The |
| 115 | +final job result is still driven by the CodeClone analysis exit code. |
| 116 | + |
| 117 | +## Permissions |
| 118 | + |
| 119 | +Recommended permissions: |
| 120 | + |
| 121 | +```yaml |
| 122 | +permissions: |
| 123 | + contents: read |
| 124 | + security-events: write |
| 125 | + pull-requests: write |
| 126 | +``` |
| 127 | + |
| 128 | +Notes: |
| 129 | + |
| 130 | +- `security-events: write` is required for SARIF upload |
| 131 | +- `pull-requests: write` is required for PR comments |
| 132 | +- if you only want gating and JSON output, you can disable `sarif` and |
| 133 | + `pr-comment` |
| 134 | + |
| 135 | +## Stable vs prerelease installs |
| 136 | + |
| 137 | +Stable: |
| 138 | + |
| 139 | +```yaml |
| 140 | +with: |
| 141 | + package-version: "" |
| 142 | +``` |
| 143 | + |
| 144 | +Explicit prerelease: |
| 145 | + |
| 146 | +```yaml |
| 147 | +with: |
| 148 | + package-version: "2.0.0b3" |
| 149 | +``` |
| 150 | + |
| 151 | +## Notes and limitations |
| 152 | + |
| 153 | +- For private repositories without GitHub Advanced Security, SARIF upload may |
| 154 | + not be available. In that case, set `sarif: "false"` and rely on the PR |
| 155 | + comment + exit code. |
| 156 | +- The baseline file must exist in the repository when `require-baseline: true`. |
| 157 | +- The action always generates a canonical JSON report, even if SARIF is |
| 158 | + disabled. |
| 159 | +- PR comments are updated in place using a hidden marker, so repeated runs do |
| 160 | + not keep adding duplicate comments. |
| 161 | +- Analysis has a 10-minute timeout. For very large repositories, consider |
| 162 | + using `extra-args: "--skip-metrics"` or narrowing the scan scope. |
| 163 | +
|
| 164 | +## See also |
| 165 | +
|
| 166 | +- [CodeClone repository](https://github.com/orenlab/codeclone) |
| 167 | +- [Documentation](https://orenlab.github.io/codeclone/) |
| 168 | +- [SARIF integration](https://orenlab.github.io/codeclone/sarif/) |
0 commit comments