Repository navigation
GitHub Action
The echoes action installs cargo echoes, scans the workspace and reports what it finds. It can review a pull request, gate a push or find reusable code in the workspace's dependencies.
on: pull_request
jobs:
echoes:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: LucaCappelletti94/cargo-echoes@v1
with:
pr-number: ${{ github.event.pull_request.number }}
functions: trueWith pr-number set, the action posts a review on the pull request instead of failing the job. Each copy that can go gets an inline comment with a suggestion that removes it and a link to the copy that stays. The review covers only the duplicates the pull request introduces. Set only-new: false to report older ones too.
Context and reuse findings follow the same filter and post as plain comments without removal suggestions. They do not trigger a request for changes. An extraction candidate with a verified GitHub source range can link a prefilled issue form, which creates nothing until someone submits it. A verified tagged request for the same range is linked when established.
The job summary includes scan results, and workflow annotations can show findings without a token. Set annotations: false to omit annotations.
Leave out pr-number and the job fails whenever it finds a duplicate, including a local context group. That suits a push to main or a scheduled run. Dependency reuse findings fail the gate only with context-fail-on-reuse: true, and a requested dependency analysis that could not complete fails the run in either mode.
A nonzero context-dependency-depth indexes the sources of the workspace's dependencies and matches local contexts against them. The job summary lists the whole reuse report in both modes, and a review posts neutral comments on the local contexts in the pull request diff. Dependency reuse explains the candidates and their actions, and Performance measures the cost.
on: push
jobs:
echoes:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Build echoes from the same commit
run: cargo install --git https://github.com/LucaCappelletti94/cargo-echoes.git --rev 1e9c6ec23582e4c87c9c36413060b2fedc7a095f --locked echoes
- uses: LucaCappelletti94/cargo-echoes@1e9c6ec23582e4c87c9c36413060b2fedc7a095f
with:
install: false
context-dependency-depth: 1
context-fail-on-reuse: trueThe Action and binary in this example use the same pinned source revision. install: false retains that binary for the scan.
With a nonzero depth, the run restores the public dependency cache before scanning and saves it after complete analysis. Its key includes runner OS and context-target. The public cache contains canonical indexes, archives and extracted published sources. Path, Git, alternate-registry and modified-source entries stay private. Cache saves are skipped for incomplete analysis and fork pull requests.
| Input | Default | Effect |
|---|---|---|
pr-number |
empty | Review this pull request instead of failing the job |
only-new |
true |
In a review, report only duplicates the pull request introduces |
threshold |
2 |
Report groups with at least this many sites |
min-tokens |
0 |
Skip smaller doctests |
functions |
false |
Run the function check |
fn-min-tokens |
empty | Skip smaller function bodies, 30 when empty |
context-blocks |
false |
Run the context check |
context-min-tokens |
empty | Skip smaller contexts, 30 when empty |
context-select |
empty | Local contexts whose matches are reported |
context-search |
empty | Contexts compared against the local selection |
context-dependency-depth |
0 |
Match local contexts against dependency sources up to this edge distance, zero stays local |
context-dev-dependencies |
false |
Include development dependency edges |
context-build-dependencies |
false |
Include build dependency edges |
context-all-optional-dependencies |
false |
Explore optional edges outside the selected features |
context-features |
empty | Comma-separated Cargo features for discovery |
context-all-features |
false |
Enable every workspace feature for discovery |
context-no-default-features |
false |
Disable default workspace features for discovery |
context-target |
empty | Target triple used for discovery |
context-cache-dir |
empty | Dependency index directory, run-local when empty |
context-check-latest |
true |
Compare each dependency against its latest published release too |
context-fail-on-reuse |
false |
Fail the gate on dependency reuse findings |
all-targets |
false |
Scan binary and example doctests too |
package |
empty | Scan one workspace member |
cwd |
repository root | Scan the workspace in this directory |
annotations |
true |
Emit workflow annotations |
dry-run |
false |
Write the review to the job summary instead of posting it |
exclude |
empty | Leave out files matching these gitignore-style globs, one per line, see Configuration |
organizations |
empty | Scan every repository of these GitHub organizations or users instead of the workspace, one per line, gate only |
repositories |
empty | Scan these OWNER/REPO repositories instead of the workspace, together with any organizations, one per line, gate only |
max-comments |
50 |
Inline comments posted per run, the rest are counted in the review body and listed in the run summary |
install |
true |
Install echoes, or use the cargo echoes already on the path |
version |
latest | The echoes version to install |
mode |
review |
review, or prepare and post for forks |
payload |
empty | Directory that prepare writes and post reads |
The action installs a prebuilt binary on Linux, macOS and Windows runners and builds from source anywhere else. A .echoes.toml in the scanned workspace sets everything the inputs leave out, such as scan-generated. threshold and min-tokens always come from the inputs.
organizations and repositories scan GitHub instead of the checked-out workspace, like Organization search. They read with the workflow token unless the job sets GH_TOKEN, which private repositories of other owners need, and they emit no annotations because the copies live in other repositories.
A pull request from a fork runs with a read-only token, so the action cannot post a review from that job. It still writes the job summary and the annotations.
To review forks too, split the work in two workflows. The first runs on the pull request with mode: prepare and uploads the scan as an artifact. The second runs on workflow_run with mode: post, downloads the artifact and posts the review with a write token. Both workflows are in examples/workflows.
The posting workflow holds a write token while a stranger's pull request is in play, so it must never check out or run the pull request's code. The pull request controls the first workflow, so the action treats the artifact as data. It reads only the head commit and head repository ids from the triggering run, posts only on the open pull request whose head matches both, rejects an artifact naming another one or holding a file over 128 MiB, and renders every comment itself with all report text escaped. GitHub's guide on workflow_run explains the risk.