Skip to main content
Version: 0.3 · v0.3.0

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.

InputCheckBlocks?
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_SOURCEThe 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:

A static overview of the enforced CI path from build and tests through the impact check to deploy or skip.

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​

CodeMeaning
0Passed, or nothing to check on purpose (the cluster already runs the target version)
1The change breaks something, or the upgrade verdict blocked — and --enforce is set
2Couldn'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​

SettingFails on
(no --enforce)never (report only)
MIROPS_ENFORCE=truea change that breaks something; an upgrade verdict of CRITICAL (blocked)
MIROPS_ENFORCE=true + MIROPS_ENFORCE_LEVEL=warningthe 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.