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: Previousrun_report.jsonfile to use for incremental issue handling
Configuration file schema:
repositories: Required list of repository URLsissues.custom_message: Optional message appended to generated issue bodiesissues.opt_outs: Optional list of repositories to analyze without publishing issuesoutputs.root_dir: Optional output root directory. Defaults tooutputsoutputs.run_name: Optional stable campaign name used as the parent folder for snapshotsoutputs.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 byrun-analysis--retry-failed: Retry records previously markedfailedwhen 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.jsonto 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¶
Prepare a configuration file listing repositories, issue settings, and outputs.
cat assets/ossr_list_url.jsonRun 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
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, andsomef_output.json. The snapshot root also containsconfig.json,analysis_results.json, andrun_report.json.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;