ossf / ossf/scorecard

Feature: Packaging check should detect cargo-dist (axodotdev) Rust release workflows

Open
#5,145 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

needs triage
Dominant language
Go
Stars
5.7k
Forks
724
Avg merge
19h 30m
Merged PRs (30d)
1

Description

Is your feature request related to a problem? Please describe.

The Packaging check reports "packaging workflow not detected" (-1) for many Rust repositories that publish multi-platform binaries (and often crates) via cargo-dist / the dist CLI in GitHub Actions. That is a false negative for a mainstream Rust packaging layout.

Scorecard already has a Rust matcher:

// checks/fileparser/github_workflow.go (IsPackagingWorkflow)
{
  // Rust packages. https://doc.rust-lang.org/cargo/reference/publishing.html
  Steps: []*JobMatcherStep{
    {
      Run: "cargo.*publish",
    },
  },
  LogText: "candidate rust publishing workflow using cargo",
},

cargo-dist workflows typically do not put a bare cargo publish step in the same top-level workflow that builds and attaches release artifacts. They use dist plan / dist build (and sometimes a separate reusable workflow for crates.io).

Concrete example

Repo: https://github.com/patchloom/patchloom
Workflow: .github/workflows/release.yml (cargo-dist plan/build + GitHub Releases + Homebrew/Scoop/npm installers + crates publish)

Public Scorecard API historically reported Packaging -1 / "packaging workflow not detected" for this project even while:

  • Multi-arch binaries are built with dist plan / dist build and uploaded to GitHub Releases
  • crates.io publish runs via cargo publish --locked --package patchloom in a reusable workflow (.github/workflows/publish-crates.yml, on: workflow_call only)
  • Homebrew formula / Scoop / npm installer packages are published from the same release pipeline

Related project note: https://github.com/patchloom/patchloom/blob/main/SECURITY.md (section "OpenSSF Scorecard notes") documents Packaging as a known cargo-dist false negative.

Why current matchers miss cargo-dist
  1. No matcher for cargo-dist / dist CLI.
    There is no JobMatcher for:

    • dist plan / dist build / dist publish (or cargo dist ...)
    • install/use of axodotdev cargo-dist binaries
    • common cargo-dist-generated workflow job shapes
  2. cargo publish in workflow_call-only reusable workflows often never credits Packaging.
    In checks/raw/github/packaging.go, after a workflow matches a packaging pattern, Scorecard requires:

    runs, err := c.RepoClient.ListSuccessfulWorkflowRuns(filepath.Base(fp))
    // ...
    if len(runs) > 0 { /* success */ }
    // else: "GitHub publishing workflow not used in runs: ..."
    

    For patchloom:

    Workflow file Pattern match Successful runs (API)
    release.yml cargo-dist dist plan/dist build (no matcher today); also may match npm if present Many
    publish-crates.yml cargo publish matches 0 (on: workflow_call only; runs are attributed to the caller, not this file)

    So pure "cargo-dist + reusable cargo publish" layouts can still fail Packaging even when crates and binaries are published on every release.

Observed behavior (live recheck)

Local scorecard --checks=Packaging on 2026-07-27 against github.com/patchloom/patchloom currently scores 10 because release.yml also has an npm publish job that matches the existing npm matcher (actions/setup-node + registry-url: https://registry.npmjs.org + npm.*publish) around job publish-npm (~line 706).

That does not mean cargo-dist is detected. A Rust-only cargo-dist project without npm (very common) still gets Packaging -1. Relying on npm as the only packaging signal for a Rust binary/crates release pipeline is incorrect.

Describe the solution you'd like
  1. Primary: add cargo-dist packaging matchers in IsPackagingWorkflow (same family as goreleaser / cargo publish), for example:

    • Run regex covering dist plan, dist build, dist publish (and optionally cargo dist ...)
    • Log text like: candidate rust publishing workflow using cargo-dist
    • Unit tests with fixture YAML modeled on cargo-dist-generated release.yml jobs
  2. Secondary (related correctness): reusable workflow_call publish jobs
    When a packaging pattern matches a workflow_call-only file with no standalone successful runs, either:

    • credit Packaging if a caller workflow with successful runs references that reusable workflow, or
    • document that cargo publish must appear in a workflow that has its own run history

    This is the same class of gap as other "matcher exists but detector never sees reality" Packaging bugs (e.g. ko dual-setup issue #5133, goreleaser fork #5131, changesets #5096).

  3. Docs: mention cargo-dist under Packaging in docs/checks.md / beginner docs once matchers land.

Default remains non-breaking

Adding matchers only expands detection; repos already scoring 10 stay 10.

Alternatives considered
  • Project-side workaround: keep a dummy cargo publish step in a workflow that has standalone successful runs — fragile and dishonest packaging signal.
  • Depend only on npm matcher: wrong for Rust-only cargo-dist projects.
  • Ignore Packaging −1 forever: fine for local SECURITY.md notes, but leaves a systemic false negative for a large Rust ecosystem segment.
Additional context

Happy to open a PR adding the cargo-dist JobMatcher + fixtures if maintainers agree on the regex / step shape.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in checks/fileparser/github_workflow.go at IsPackagingWorkflow and review checks/raw/github/packaging.go, especially successful-run handling for workflow_call files. Add cargo-dist fixture coverage for the named dist commands, then run the Packaging matcher tests; done means cargo-dist workflows are detected and the reusable-workflow behavior is resolved or documented, with docs/checks.md updated.

Written by the indexing model from the issue text.

Assessment

Tech stack
github-actions, go, rust
Domain
ci-cd, devtools, release
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.