use cases

Stop GPL Code at the Pull Request: A Licence Check in CI

The cheapest moment to deal with copied code is before it merges. Once it ships, a GPL function in a closed product means a release to pull back and a rewrite under pressure. In a pull request it means a red build and a few lines to replace.

remixware check is made for that moment. It scans the project, applies your policy, prints what breaks it, and exits with status 1, so the build stops. When nothing breaks the policy it prints PASS and exits with 0. A check that couldn’t do its job exits with 2 instead of passing: a file it can’t read, or a folder with no source files to scan, which usually means a wrong path or an --exclude that covers everything.

A failed CI run: remixware check lists a GPL conflict, an AGPL conflict, code with no licence and missing attribution, then FAIL: 8 findings break the policy.

A Step for GitHub Actions

This job checks a Go project against the modules it depends on. For a JavaScript project, run npm ci and index node_modules instead; for Python, index the virtual environment.

name: Licence check
on: [pull_request]

jobs:
  remixware:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: stable
      - run: go mod download
      - name: Install Remixware
        run: |
          mkdir -p "$HOME/bin"
          curl -sSL https://github.com/softdevstudio/remixware/releases/latest/download/remixware_linux_amd64.tar.gz \
            | tar -xz -C "$HOME/bin" ./remixware
          echo "$HOME/bin" >> "$GITHUB_PATH"
      - name: Check copied code
        run: |
          remixware index "$(go env GOMODCACHE)" --out deps.rmx --quiet
          remixware check . --index deps.rmx --html remixware-report.html
      - name: Keep the report
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: remixware-report
          path: remixware-report.html

The report is kept even when the check fails, so whoever looks at the red build can open it and see the copied lines next to their source.

What Fails the Build

By default check fails on three statuses: conflict, no-license and attribution-missing. Findings marked review are listed but don’t fail it. A copy that needs a review and its notice, such as an MPL 2.0 file, counts as attribution-missing until your notices carry it, so the check still stops for the part that’s certain. A .remixware.json file in the project changes that:

{
  "fail_on": ["conflict", "no-license"],
  "ignore": ["testdata/**"],
  "allow": [
    {"component": "github.com/acme/*", "reason": "Acme gave us a commercial licence in 2025"}
  ]
}

Starting with conflicts and missing licences alone is a gentle way in: those are the findings that need code changed. Add attribution-missing once your notices file is up to date. remixware notice . --index deps.rmx --out THIRD_PARTY_NOTICES.md writes the missing entries for you, and the next check passes once you’ve filled in anything it couldn’t find, such as a copyright line.

Allow rules record decisions. Each needs a reason, and the reason shows up in the text, HTML and JSON reports, so a finding you accepted on purpose doesn’t look like one somebody missed.

Adding SCANOSS

--scanoss works in CI too, with one thing to plan for. Hosted runners are shared by many projects, so the free SCANOSS service’s usage limits may already be used up when your job asks. Keep a SCANOSS API key as a repository secret and pass it in:

      - name: Check copied code
        env:
          SCANOSS_API_KEY: ${{ secrets.SCANOSS_API_KEY }}
        run: |
          remixware index "$(go env GOMODCACHE)" --out deps.rmx --quiet
          remixware check . --index deps.rmx --scanoss --html remixware-report.html

Pull requests from forks don’t get repository secrets, so their checks ask the free service. If the service turns the check away, it exits with 2 and says why, so the build can’t pass without the answers.

A Clean Pass

On a project with nothing copied, remixware check . --index deps.rmx --quiet prints two lines:

No copied code found.
PASS: no findings break the policy (fail on: conflict, no-license, attribution-missing).

The reference lists every option of check, and the quick start shows the same steps by hand.