Use it in CI/CD
mirops scan reads the mirror report and runs the checks its inputs ask for. A pipeline is configured only through MIROPS_* environment variables, so it doesn't change when an upgrade window opens or closes.
| Input | Check | Blocks? |
|---|---|---|
MIROPS_FILE (-f) | The impact of what you're about to apply — manifests or a Terraform plan. See Impact of a change. | With --enforce |
MIROPS_NAMESPACE (-n) | A namespace's current state: one, a comma-separated list, or all. With -f, also the only namespaces the change is judged in. | Never — informational |
MIROPS_UPGRADE=true + MIROPS_UPGRADE_SOURCE | The upgrade verdict of the analysis report you point at. The target version comes from that report. | With --enforce |
Give several and they all run; the impact and the upgrade verdict set the exit code. Give none and the CLI exits 2 ("nothing to scan").
The impact stage
Put Mirops between your tests and your deploy. When the change breaks something, the impact job fails and the deploy job — which needs it — doesn't run:
This static illustration provides a quick visual summary of the same flow:
jobs:
impact:
needs: test
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # OIDC: assume an AWS role, no stored keys
env:
MIROPS_SOURCE: s3://my-reports/prod/default.mirops
MIROPS_NAMESPACE: payments # the namespaces this repo deploys to
MIROPS_ENFORCE: "true"
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ vars.AWS_ROLE_ARN }} # s3:GetObject on the report
aws-region: us-east-1
- name: Install mirops CLI
run: |
mkdir -p "$RUNNER_TEMP/bin"
curl -fsSL -o "$RUNNER_TEMP/bin/mirops" \
https://github.com/miropshq/mirops-cli/releases/download/v0.3.0/mirops-linux-amd64
chmod +x "$RUNNER_TEMP/bin/mirops"
echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH"
- name: Impact of the change
run: helm template payments ./chart | mirops scan -f -
# or: mirops scan -f k8s/
# or: terraform show -json plan.out | mirops scan -f -
deploy:
needs: impact # skipped when the impact check blocks
runs-on: ubuntu-latest
steps:
- run: helm upgrade --install payments ./chart
With MIROPS_NAMESPACE, the repo is judged only on its own namespaces — another team's broken component doesn't block it. Without MIROPS_ENFORCE, the same stage reports and never fails, a good way to start.
Exit codes
| Code | Meaning |
|---|---|
0 | Passed, or nothing to check on purpose (the cluster already runs the target version) |
1 | The change breaks something, or the upgrade verdict blocked — and --enforce is set |
2 | Couldn't evaluate — bad input, unreadable or stale report, a source to render first (values.yaml, .tf, …), a -n in neither the mirror nor the change, MIROPS_UPGRADE=true without MIROPS_UPGRADE_SOURCE, upgrade analysis off in the cluster. Never a pass. |
Enforcement levels
| Setting | Fails on |
|---|---|
(no --enforce) | never (report only) |
MIROPS_ENFORCE=true | a change that breaks something; an upgrade verdict of CRITICAL (blocked) |
MIROPS_ENFORCE=true + MIROPS_ENFORCE_LEVEL=warning | the upgrade gate also fails on WARNING |
A cluster-upgrade pipeline
Set the variables once; flip MIROPS_UPGRADE for the upgrade window. When the cluster already runs the analysis's target version the check reports skipped and passes, so leaving it on after the upgrade is harmless.
jobs:
upgrade:
runs-on: ubuntu-latest
env:
MIROPS_SOURCE: s3://my-reports/prod/default.mirops
MIROPS_UPGRADE: ${{ vars.MIROPS_UPGRADE }} # "true" during the upgrade window
MIROPS_UPGRADE_SOURCE: s3://my-reports/prod/to-1-35.mirops
MIROPS_ENFORCE: "true"
AWS_REGION: us-east-1
steps:
- name: Install mirops CLI
run: |
mkdir -p "$RUNNER_TEMP/bin"
curl -fsSL -o "$RUNNER_TEMP/bin/mirops" \
https://github.com/miropshq/mirops-cli/releases/download/v0.3.0/mirops-linux-amd64
chmod +x "$RUNNER_TEMP/bin/mirops"
echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH"
- name: Gate on the verdict
run: mirops scan
- name: Upgrade
run: terraform apply -auto-approve
The two reports can live in different places: each *_SOURCE is read with the pipeline's credentials for its scheme (s3:// → AWS, azure:// → Azure). The upgrade step only runs if the gate passes.
Upgrade analysis must be on
The upgrade check needs upgrade analysis on in the mirops install (Helm upgrade.enabled=true). When the mirror report says it's off, MIROPS_UPGRADE=true exits 2 with the command to turn it on — a stale analysis report is never gated on.
A namespace's state in a deploy pipeline
MIROPS_SOURCE=s3://my-reports/prod/default.mirops mirops scan -n payments
It prints what is at risk in payments right now, what depends on each component, and its risk — without adding load on the cluster, since it reads the report. It never blocks: a component that's down may be exactly what the deploy fixes.
The pattern
Mirops is the gate, not the hand on the lever. Run the upgrade check before the upgrade to decide. After it, the check reports skipped — the cluster runs the target version — and mirops scan -n all shows from the mirror whether anything is at risk once the next rebuild lands.
See the CLI reference for every flag.