Usage

Command Line Interface

The bot provides three main commands:

Run Analysis

Run analysis and decision generation from a single configuration file. This command only runs the analysis: it computes issue lifecycle decisions and writes reports, but does not call the GitHub or GitLab APIs.

sw-metadata-bot run-analysis \
  --config-file assets/ossr_list_url.json

Options:

  • --config-file: Unified campaign configuration with repositories, issue settings, and output layout

  • --snapshot-tag: Optional snapshot folder name override for the current run

  • --previous-report: Previous run_report.json file to use for incremental issue handling

Configuration file schema:

  • repositories: Required list of repository URLs

  • issues.custom_message: Optional message appended to generated issue bodies

  • issues.opt_outs: Optional list of repositories to analyze without publishing issues

  • outputs.root_dir: Optional output root directory. Defaults to outputs

  • outputs.run_name: Optional stable campaign name used as the parent folder for snapshots

  • outputs.snapshot_tag_format: Optional strftime pattern for generated snapshot folders. Defaults to %Y%m%d

Publish from a generated analysis snapshot:

Publish reuses the decisions already written by run-analysis and applies the corresponding GitHub or GitLab side effects to create, update, or close issues. This separation allows for manual review and adjustments of the generated reports before publishing.

sw-metadata-bot publish --analysis-root outputs/ossr/20260325

Options:

  • --analysis-root: Required snapshot folder generated by run-analysis

  • --retry-failed: Retry records previously marked failed when transient and eligible

Retrying failed publish records:

When publish fails because of transient API conditions (for example rate limits, temporary outages, or short-lived connectivity errors), rerun publish with the retry flag after fixing the cause or waiting for backoff.

sw-metadata-bot publish \
   --analysis-root outputs/ossr/<snapshot> \
   --retry-failed

Notes:

  • Records that were already posted remain idempotent and are skipped.

  • Failed records classified as non-transient (for example auth/permission errors)

    are not retried automatically.

  • Retry metadata is persisted in run_report.json to track attempts and timing.

Verify Tokens

Check whether the configured GitHub and GitLab tokens are available and have the required permissions.

sw-metadata-bot verify-tokens

Examples:

sw-metadata-bot verify-tokens --github
sw-metadata-bot verify-tokens --gitlab --json

Options:

  • --github: Check only the GitHub token

  • --gitlab: Check only the GitLab token

  • --json: Emit JSON output instead of the formatted terminal report

Example Workflow

  1. Prepare a configuration file listing repositories, issue settings, and outputs.

    cat assets/ossr_list_url.json
    
  2. Run analysis in dry-run decision mode:

    sw-metadata-bot run-analysis --config-file assets/ossr_list_url.json
    

    To compare with an earlier run explicitly, pass the previous run report:

    sw-metadata-bot run-analysis \
      --config-file assets/ossr_list_url.json \
      --previous-report outputs/ossr/20260325/run_report.json
    
  3. Review the generated files under the configured output directory.

    Each repository gets its own sanitized output folder containing issue_report.md, pitfall.jsonld, report.json, and somef_output.json. The snapshot root also contains config.json, analysis_results.json, and run_report.json.

  4. Publish the reviewed snapshot:

    sw-metadata-bot publish --analysis-root outputs/ossr/<snapshot>
    

Decision Tree for Issue Creation

The bot uses a decision tree to determine whether to create an issue for each repository. The main factors include:

  • Whether the repository has already been analyzed in a previous snapshot

  • Whether the repository has changed since last analysis (based on commit id)

  • Whether the analysis detects pitfalls and warnings

  • Whether a previous issue is already open for the repository

  • Whether an unsubscribe comment was previously recorded

        %%{init: {
  "flowchart": {
    "htmlLabels": true,
    "useMaxWidth": true,
    "nodeSpacing": 35,
    "rankSpacing": 45
  },
  "themeVariables": {
    "fontSize": "18px"
  }
}}%%
flowchart TB
    repo([Repository]) --> prev{Previous analysis exists?}

    prev -- No --> full[Run analysis + create issue]

    prev -- Yes --> unsub{Unsubscribed?}
    unsub -- Yes --> blacklist[Add to blacklist and stop]

    unsub -- No --> updated{Repo updated?}
    updated -- No --> copy[Reuse previous analysis and stop]

    updated -- Yes --> run[Run analysis]
    run --> warn{Pitfalls or warnings found?}

    warn -- No --> openNoWarn{Previous issue open?}
    openNoWarn -- Yes --> close[Close issue]
    openNoWarn -- No --> stop1[Stop]

    warn -- Yes --> same{Same results as previous run?}

    same -- No --> openA{Previous issue open?}
    openA -- Yes --> update[Update issue]
    openA -- No --> newA[Open new issue]

    same -- Yes --> openB{Previous issue open?}
    openB -- Yes --> stop2[Stop]
    openB -- No --> newA[Open new issue]

   classDef orange fill:#ffedd5,stroke:#c2410c,color:#7c2d12,stroke-width:2px;
   classDef green fill:#dcfce7,stroke:#15803d,color:#14532d,stroke-width:2px;
   classDef red fill:#fee2e2,stroke:#b91c1c,color:#7f1d1d,stroke-width:2px;


   class full green;
   class blacklist red;
   class copy red;
   class close green;
   class stop1 red;
   class update orange;
   class newA green;
   class stop2 red;