hyperi-ci 2.7.2__tar.gz → 2.7.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/.github/workflows/ci.yml +20 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/.github/workflows/go-ci.yml +24 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/.github/workflows/python-ci.yml +24 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/.github/workflows/rust-ci.yml +24 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/.github/workflows/ts-ci.yml +24 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/.hyperi-ci.yaml +4 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/PKG-INFO +14 -1
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/README.md +13 -0
- hyperi_ci-2.7.3/VERSION +1 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/ARCHITECTURE.md +1 -1
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/DESIGN.md +1 -0
- hyperi_ci-2.7.3/docs/quality-gate.md +142 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/cli.py +25 -4
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/config/defaults.yaml +1 -4
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/dispatch.py +8 -1
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/golang/quality.py +10 -13
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/python/quality.py +14 -16
- hyperi_ci-2.7.3/src/hyperi_ci/languages/quality_common.py +131 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/rust/quality.py +10 -13
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/typescript/quality.py +10 -11
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/quality/commit_validation.py +1 -1
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/quality/gitleaks.py +3 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/quality/predicted_bump.py +2 -1
- hyperi_ci-2.7.3/src/hyperi_ci/quality/semgrep.py +98 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/watch.py +45 -0
- hyperi_ci-2.7.3/tests/unit/test_quality_strict.py +134 -0
- hyperi_ci-2.7.3/tests/unit/test_semgrep.py +71 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_typescript_quality.py +7 -6
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_watch.py +94 -0
- hyperi_ci-2.7.2/VERSION +0 -1
- hyperi_ci-2.7.2/src/hyperi_ci/languages/quality_common.py +0 -48
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/.gitattributes +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/.github/actions/predict-version/action.yml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/.github/actions/setup-osv-scanner/action.yml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/.github/actions/setup-runtime/action.yml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/.github/actions/setup-semantic-release/action.yml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/.github/actions/setup-semantic-release/default.releaserc.json +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/.github/workflows/_release-tail.yml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/.gitignore +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/.releaserc.yaml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/AI-TRAINING-POLICY.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/CHANGELOG.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/COMMERCIAL.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/CONTRIBUTING.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/LICENSE +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/SECURITY.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/config/commit-types.yaml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/config/org.yaml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/config/runners.yaml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/config/secrets-access.yaml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/config/versions.yaml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/ARC-RUNNERS.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/CI-LESSONS.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/FLOW.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/JFROG-MIGRATION.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/LESSONS.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/MIGRATION-GUIDE.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/PGO-WORKLOAD-GUIDE.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/README.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/dependencies/DEPS-PINNING.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/dependencies/WORKFLOW-PINNING.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/deployment/CONTRACT-IDENTITY.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/deployment/CONTRACT.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/deployment/TIERS.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/deployment-contract.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/languages/GO.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/languages/PYTHON.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/languages/RUST.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/languages/TYPESCRIPT.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/migration/CODEBERG-SECRETS-AND-CI.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/migration/JFROG.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/migration/ONBOARDING.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/migration/codeberg-secrets-and-ci.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/migration/codeberg.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/migration/deployment-contract-tier3.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/runtime/PGO-BOLT.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/runtime/RUNNERS.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/runtime/TESTENV.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/rust.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/docs/typescript.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/pyproject.toml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/renovate.json +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/robots.txt +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/scripts/check-workflow-interfaces.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/scripts/pre-commit-versions.sh +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/scripts/recover-tags.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/scripts/setup-rust-dev.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/scripts/sync-secrets-access.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/scripts/update-versions.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/argocd/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/argocd/gitops_push.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/argocd/stage.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/common.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/config/native-deps/golang.yaml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/config/native-deps/python.yaml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/config/native-deps/rust.yaml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/config/native-deps/typescript.yaml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/config/org.yaml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/config/toolchains/gcc.yaml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/config/toolchains/llvm.yaml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/config.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/container/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/container/binary_stage.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/container/build.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/container/compose.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/container/detect.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/container/labels.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/container/manifest.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/container/registry.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/container/stage.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/container/templates.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/deployment/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/deployment/cli.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/deployment/contract.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/deployment/detect.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/deployment/overlay/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/deployment/overlay/anchors/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/deployment/overlay/anchors/argocd.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/deployment/overlay/anchors/dockerfile.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/deployment/overlay/anchors/helm.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/deployment/overlay/cli.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/deployment/overlay/errors.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/deployment/overlay/model.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/deployment/overlay/render.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/deployment/registry.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/deployment/scaffold.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/deployment/stage.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/deployment/topology/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/deployment/topology/resolve.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/deployment/topology/stitch.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/detect.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gh.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/.gitbook.yaml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/.gitignore +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/CODEOWNERS +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/LICENSE +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/README.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/argocd/README.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/argocd/applicationsets/.gitkeep +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/argocd/appprojects/.gitkeep +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/argocd/bootstrap/.gitkeep +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/docs/concepts/architecture.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/docs/concepts/overview.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/docs/how-to/add-app.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/docs/how-to/add-environment.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/docs/how-to/add-topology.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/docs/index.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/docs/operations/disaster-recovery.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/docs/operations/rollback.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/docs/quickstart.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/docs/reference/sync-waves.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/docs/reference/topology-schema.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/mkdocs.yml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/pull_request_template.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/terraform/README.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/terraform/aws/environments/.gitkeep +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/terraform/aws/modules/.gitkeep +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/terraform/rancher/clusters/.gitkeep +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/terraform/rancher/modules/.gitkeep +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/topologies/README.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/values/.gitkeep +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/workflows/docs.yaml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/workflows/stitch-and-publish.yaml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/gitops_templates/workflows/validate.yaml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/helm/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/helm/stage.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/init.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/init_gitops.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/install_deps.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/_build_common.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/golang/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/golang/build.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/golang/publish.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/golang/test.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/python/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/python/build.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/python/publish.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/python/test.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/rust/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/rust/build.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/rust/optimize.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/rust/pgo.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/rust/publish.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/rust/test.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/typescript/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/typescript/_common.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/typescript/build.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/typescript/install_deps.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/typescript/publish.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/languages/typescript/test.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/licenses.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/logs.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/migrate.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/native_deps.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/publish/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/publish/binaries.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/publish/dispatch.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/publish_binaries.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/push.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/quality/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/quality/ignores.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/quality/osv_scanner.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/release.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/stamp.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/trigger.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/src/hyperi_ci/upgrade.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/templates/pgo-workload/README.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/templates/pgo-workload/grpc-server.sh +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/templates/pgo-workload/http-server.sh +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/templates/pgo-workload/kafka-consumer.sh +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/templates/pgo-workload/kafka-producer.sh +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/templates/pgo-workload/multi-protocol.sh +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/templates/testenv/README.md +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/templates/testenv/clickhouse-low-mem.xml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/templates/testenv/clickhouse.compose.yaml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/templates/testenv/redpanda.compose.yaml +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/argocd/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/argocd/test_gitops_push.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/argocd/test_stage.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/deployment/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/deployment/overlay/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/deployment/overlay/test_argocd_anchors.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/deployment/overlay/test_cli.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/deployment/overlay/test_dockerfile_anchors.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/deployment/overlay/test_helm_anchors.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/deployment/overlay/test_model.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/deployment/topology/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/deployment/topology/test_resolve.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/deployment/topology/test_stitch.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/helm/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/helm/test_stage.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/helm/test_stage_topology_mode.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/integration/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/integration/test_rust_build_optimize.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/deployment/__init__.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/deployment/test_contract.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/deployment/test_detect_tier.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/deployment/test_emit_artefacts_cli.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/deployment/test_registry_cascade.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/deployment/test_scaffold.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/deployment/test_stage.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_build_common.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_cli.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_cli_init_gitops.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_cli_stitch.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_commit_validation.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_common.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_config.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_container_binary_stage.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_container_build.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_container_compose.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_container_detect.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_container_labels.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_container_manifest.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_container_registry.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_container_stage.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_container_templates.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_detect.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_dispatch_alias.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_dispatch_status.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_gh.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_init.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_init_gitops.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_init_topology.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_licenses.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_migrate.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_native_deps.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_osv_scanner.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_predicted_bump.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_publish.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_publish_dispatch.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_push.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_quality_ignore_wiring.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_quality_ignores.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_recover_tags.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_release_version.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_rust_optimize.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_rust_pgo.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_rust_quality.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_stamp.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_update_versions.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_upgrade.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_workflow_consistency.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/tests/unit/test_workflow_interfaces.py +0 -0
- {hyperi_ci-2.7.2 → hyperi_ci-2.7.3}/uv.lock +0 -0
|
@@ -47,11 +47,23 @@ concurrency:
|
|
|
47
47
|
group: ${{ github.workflow }}-${{ inputs.tag || github.ref }}
|
|
48
48
|
cancel-in-progress: true
|
|
49
49
|
|
|
50
|
+
# Least-privilege GITHUB_TOKEN default for every job (CodeQL
|
|
51
|
+
# actions/missing-workflow-permissions). Two jobs elevate: release-tail
|
|
52
|
+
# (passes write down to _release-tail.yml -- semantic-release commit/tag +
|
|
53
|
+
# GHCR) and plan (semantic-release push-access verify on a publish predict).
|
|
54
|
+
# commit-check / quality / test / build are read-only.
|
|
55
|
+
permissions:
|
|
56
|
+
contents: read
|
|
57
|
+
|
|
50
58
|
jobs:
|
|
51
59
|
plan:
|
|
52
60
|
name: Plan
|
|
53
61
|
if: github.event.pull_request.head.repo.fork != true
|
|
54
62
|
runs-on: ubuntu-latest
|
|
63
|
+
# predict-version runs semantic-release, whose git plugin verifies push
|
|
64
|
+
# access (a `git push --dry-run`) on a publish predict -- needs write.
|
|
65
|
+
permissions:
|
|
66
|
+
contents: write
|
|
55
67
|
outputs:
|
|
56
68
|
run-checks: ${{ steps.predict.outputs.run-checks }}
|
|
57
69
|
run-build: ${{ steps.predict.outputs.run-build }}
|
|
@@ -218,6 +230,14 @@ jobs:
|
|
|
218
230
|
release-tail:
|
|
219
231
|
name: Release tail
|
|
220
232
|
needs: [plan, build]
|
|
233
|
+
# Elevated + passed to _release-tail.yml: its tag-and-publish job commits +
|
|
234
|
+
# tags (contents), pushes GHCR (packages) and runs the semantic-release GH
|
|
235
|
+
# plugin (issues + pull-requests). Capped by the caller's grant.
|
|
236
|
+
permissions:
|
|
237
|
+
contents: write
|
|
238
|
+
packages: write
|
|
239
|
+
issues: write
|
|
240
|
+
pull-requests: write
|
|
221
241
|
# Local ref (dogfood): a change to the shared release tail is exercised
|
|
222
242
|
# on hyperi-ci's own CI before any consumer pins it. The tail's own
|
|
223
243
|
# tag-and-publish job is gated on will-publish == 'true', so a non-publish
|
|
@@ -106,6 +106,18 @@ concurrency:
|
|
|
106
106
|
env:
|
|
107
107
|
HYPERCI_PUBLISH_TARGET: ${{ inputs.publish-target }}
|
|
108
108
|
HYPERCI_INSTALL: uvx --no-cache --refresh hyperi-ci
|
|
109
|
+
# Rare edge-case escape hatch: set the HYPERCI_QUALITY_SKIP repo/org
|
|
110
|
+
# variable (e.g. "semgrep") to force-skip a quality tool whose false
|
|
111
|
+
# positive is halting CI, until the real fix lands. Empty when unset.
|
|
112
|
+
HYPERCI_QUALITY_SKIP: ${{ vars.HYPERCI_QUALITY_SKIP }}
|
|
113
|
+
|
|
114
|
+
# Least-privilege GITHUB_TOKEN default for every job (CodeQL
|
|
115
|
+
# actions/missing-workflow-permissions). Two jobs elevate: release-tail
|
|
116
|
+
# (passes write down to _release-tail.yml -- semantic-release commit/tag +
|
|
117
|
+
# GHCR) and plan (semantic-release push-access verify on a publish predict).
|
|
118
|
+
# commit-check / quality / test / build are read-only.
|
|
119
|
+
permissions:
|
|
120
|
+
contents: read
|
|
109
121
|
|
|
110
122
|
jobs:
|
|
111
123
|
# ---------------------------------------------------------------------------
|
|
@@ -116,6 +128,10 @@ jobs:
|
|
|
116
128
|
name: Plan
|
|
117
129
|
if: github.event.pull_request.head.repo.fork != true
|
|
118
130
|
runs-on: ubuntu-latest
|
|
131
|
+
# predict-version runs semantic-release, whose git plugin verifies push
|
|
132
|
+
# access (a `git push --dry-run`) on a publish predict -- needs write.
|
|
133
|
+
permissions:
|
|
134
|
+
contents: write
|
|
119
135
|
outputs:
|
|
120
136
|
run-checks: ${{ steps.predict.outputs.run-checks }}
|
|
121
137
|
run-build: ${{ steps.predict.outputs.run-build }}
|
|
@@ -370,6 +386,14 @@ jobs:
|
|
|
370
386
|
release-tail:
|
|
371
387
|
name: Release tail
|
|
372
388
|
needs: [plan, build]
|
|
389
|
+
# Elevated + passed to _release-tail.yml: its tag-and-publish job commits +
|
|
390
|
+
# tags (contents), pushes GHCR (packages) and runs the semantic-release GH
|
|
391
|
+
# plugin (issues + pull-requests). Capped by the caller's grant.
|
|
392
|
+
permissions:
|
|
393
|
+
contents: write
|
|
394
|
+
packages: write
|
|
395
|
+
issues: write
|
|
396
|
+
pull-requests: write
|
|
373
397
|
uses: hyperi-io/hyperi-ci/.github/workflows/_release-tail.yml@main
|
|
374
398
|
with:
|
|
375
399
|
language: golang
|
|
@@ -110,6 +110,18 @@ concurrency:
|
|
|
110
110
|
env:
|
|
111
111
|
HYPERCI_PUBLISH_TARGET: ${{ inputs.publish-target }}
|
|
112
112
|
HYPERCI_INSTALL: uvx --no-cache --refresh hyperi-ci
|
|
113
|
+
# Rare edge-case escape hatch: set the HYPERCI_QUALITY_SKIP repo/org
|
|
114
|
+
# variable (e.g. "semgrep") to force-skip a quality tool whose false
|
|
115
|
+
# positive is halting CI, until the real fix lands. Empty when unset.
|
|
116
|
+
HYPERCI_QUALITY_SKIP: ${{ vars.HYPERCI_QUALITY_SKIP }}
|
|
117
|
+
|
|
118
|
+
# Least-privilege GITHUB_TOKEN default for every job (CodeQL
|
|
119
|
+
# actions/missing-workflow-permissions). Two jobs elevate: release-tail
|
|
120
|
+
# (passes write down to _release-tail.yml -- semantic-release commit/tag +
|
|
121
|
+
# GHCR) and plan (semantic-release push-access verify on a publish predict).
|
|
122
|
+
# commit-check / quality / test / build are read-only.
|
|
123
|
+
permissions:
|
|
124
|
+
contents: read
|
|
113
125
|
|
|
114
126
|
jobs:
|
|
115
127
|
# ---------------------------------------------------------------------------
|
|
@@ -121,6 +133,10 @@ jobs:
|
|
|
121
133
|
name: Plan
|
|
122
134
|
if: github.event.pull_request.head.repo.fork != true
|
|
123
135
|
runs-on: ubuntu-latest
|
|
136
|
+
# predict-version runs semantic-release, whose git plugin verifies push
|
|
137
|
+
# access (a `git push --dry-run`) on a publish predict -- needs write.
|
|
138
|
+
permissions:
|
|
139
|
+
contents: write
|
|
124
140
|
outputs:
|
|
125
141
|
run-checks: ${{ steps.predict.outputs.run-checks }}
|
|
126
142
|
run-build: ${{ steps.predict.outputs.run-build }}
|
|
@@ -367,6 +383,14 @@ jobs:
|
|
|
367
383
|
release-tail:
|
|
368
384
|
name: Release tail
|
|
369
385
|
needs: [plan, build]
|
|
386
|
+
# Elevated + passed to _release-tail.yml: its tag-and-publish job commits +
|
|
387
|
+
# tags (contents), pushes GHCR (packages) and runs the semantic-release GH
|
|
388
|
+
# plugin (issues + pull-requests). Capped by the caller's grant.
|
|
389
|
+
permissions:
|
|
390
|
+
contents: write
|
|
391
|
+
packages: write
|
|
392
|
+
issues: write
|
|
393
|
+
pull-requests: write
|
|
370
394
|
uses: hyperi-io/hyperi-ci/.github/workflows/_release-tail.yml@main
|
|
371
395
|
with:
|
|
372
396
|
language: python
|
|
@@ -118,6 +118,18 @@ env:
|
|
|
118
118
|
# publish), or `publish-target: both`, or a from-head dispatch (issue #35 —
|
|
119
119
|
# a from-head release is GA, not a dev pre-release).
|
|
120
120
|
HYPERCI_CHANNEL: ${{ (inputs.tag != '' || inputs.publish-target == 'both' || inputs.from-head == 'true') && 'release' || '' }}
|
|
121
|
+
# Rare edge-case escape hatch: set the HYPERCI_QUALITY_SKIP repo/org
|
|
122
|
+
# variable (e.g. "semgrep") to force-skip a quality tool whose false
|
|
123
|
+
# positive is halting CI, until the real fix lands. Empty when unset.
|
|
124
|
+
HYPERCI_QUALITY_SKIP: ${{ vars.HYPERCI_QUALITY_SKIP }}
|
|
125
|
+
|
|
126
|
+
# Least-privilege GITHUB_TOKEN default for every job (CodeQL
|
|
127
|
+
# actions/missing-workflow-permissions). Two jobs elevate: release-tail
|
|
128
|
+
# (passes write down to _release-tail.yml -- semantic-release commit/tag +
|
|
129
|
+
# GHCR) and plan (semantic-release push-access verify on a publish predict).
|
|
130
|
+
# commit-check / quality / test / build are read-only.
|
|
131
|
+
permissions:
|
|
132
|
+
contents: read
|
|
121
133
|
|
|
122
134
|
jobs:
|
|
123
135
|
# ---------------------------------------------------------------------------
|
|
@@ -136,6 +148,10 @@ jobs:
|
|
|
136
148
|
name: Plan
|
|
137
149
|
if: github.event.pull_request.head.repo.fork != true
|
|
138
150
|
runs-on: ubuntu-latest
|
|
151
|
+
# predict-version runs semantic-release, whose git plugin verifies push
|
|
152
|
+
# access (a `git push --dry-run`) on a publish predict -- needs write.
|
|
153
|
+
permissions:
|
|
154
|
+
contents: write
|
|
139
155
|
outputs:
|
|
140
156
|
run-checks: ${{ steps.predict.outputs.run-checks }}
|
|
141
157
|
run-build: ${{ steps.predict.outputs.run-build }}
|
|
@@ -424,6 +440,14 @@ jobs:
|
|
|
424
440
|
release-tail:
|
|
425
441
|
name: Release tail
|
|
426
442
|
needs: [plan, build]
|
|
443
|
+
# Elevated + passed to _release-tail.yml: its tag-and-publish job commits +
|
|
444
|
+
# tags (contents), pushes GHCR (packages) and runs the semantic-release GH
|
|
445
|
+
# plugin (issues + pull-requests). Capped by the caller's grant.
|
|
446
|
+
permissions:
|
|
447
|
+
contents: write
|
|
448
|
+
packages: write
|
|
449
|
+
issues: write
|
|
450
|
+
pull-requests: write
|
|
427
451
|
uses: hyperi-io/hyperi-ci/.github/workflows/_release-tail.yml@main
|
|
428
452
|
with:
|
|
429
453
|
language: rust
|
|
@@ -108,6 +108,18 @@ concurrency:
|
|
|
108
108
|
env:
|
|
109
109
|
HYPERCI_PUBLISH_TARGET: ${{ inputs.publish-target }}
|
|
110
110
|
HYPERCI_INSTALL: uvx --no-cache --refresh hyperi-ci
|
|
111
|
+
# Rare edge-case escape hatch: set the HYPERCI_QUALITY_SKIP repo/org
|
|
112
|
+
# variable (e.g. "semgrep") to force-skip a quality tool whose false
|
|
113
|
+
# positive is halting CI, until the real fix lands. Empty when unset.
|
|
114
|
+
HYPERCI_QUALITY_SKIP: ${{ vars.HYPERCI_QUALITY_SKIP }}
|
|
115
|
+
|
|
116
|
+
# Least-privilege GITHUB_TOKEN default for every job (CodeQL
|
|
117
|
+
# actions/missing-workflow-permissions). Two jobs elevate: release-tail
|
|
118
|
+
# (passes write down to _release-tail.yml -- semantic-release commit/tag +
|
|
119
|
+
# GHCR) and plan (semantic-release push-access verify on a publish predict).
|
|
120
|
+
# commit-check / quality / test / build are read-only.
|
|
121
|
+
permissions:
|
|
122
|
+
contents: read
|
|
111
123
|
|
|
112
124
|
jobs:
|
|
113
125
|
# ---------------------------------------------------------------------------
|
|
@@ -118,6 +130,10 @@ jobs:
|
|
|
118
130
|
name: Plan
|
|
119
131
|
if: github.event.pull_request.head.repo.fork != true
|
|
120
132
|
runs-on: ubuntu-latest
|
|
133
|
+
# predict-version runs semantic-release, whose git plugin verifies push
|
|
134
|
+
# access (a `git push --dry-run`) on a publish predict -- needs write.
|
|
135
|
+
permissions:
|
|
136
|
+
contents: write
|
|
121
137
|
outputs:
|
|
122
138
|
run-checks: ${{ steps.predict.outputs.run-checks }}
|
|
123
139
|
run-build: ${{ steps.predict.outputs.run-build }}
|
|
@@ -378,6 +394,14 @@ jobs:
|
|
|
378
394
|
release-tail:
|
|
379
395
|
name: Release tail
|
|
380
396
|
needs: [plan, build]
|
|
397
|
+
# Elevated + passed to _release-tail.yml: its tag-and-publish job commits +
|
|
398
|
+
# tags (contents), pushes GHCR (packages) and runs the semantic-release GH
|
|
399
|
+
# plugin (issues + pull-requests). Capped by the caller's grant.
|
|
400
|
+
permissions:
|
|
401
|
+
contents: write
|
|
402
|
+
packages: write
|
|
403
|
+
issues: write
|
|
404
|
+
pull-requests: write
|
|
381
405
|
uses: hyperi-io/hyperi-ci/.github/workflows/_release-tail.yml@main
|
|
382
406
|
with:
|
|
383
407
|
language: typescript
|
|
@@ -33,3 +33,7 @@ quality:
|
|
|
33
33
|
- python.lang.compatibility.python36.python36-compatibility-importlib2
|
|
34
34
|
- python.lang.compatibility.python37.python37-compatibility-importlib2
|
|
35
35
|
reason: "importlib.resources is stdlib; repo requires-python >= 3.12, no py<3.9 support"
|
|
36
|
+
- tool: semgrep
|
|
37
|
+
ids:
|
|
38
|
+
- yaml.github-actions.security.github-actions-mutable-action-tag.github-actions-mutable-action-tag
|
|
39
|
+
reason: "gitops_templates/ ships floating @vN action refs as a readable starting point; downstream repos pin via their own Renovate. This repo's own workflows are SHA-pinned (versions.yaml + pre-commit hook) so the rule is redundant here. Rule-scoped, not a path exclude, so other semgrep rules still cover the templates."
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hyperi-ci
|
|
3
|
-
Version: 2.7.
|
|
3
|
+
Version: 2.7.3
|
|
4
4
|
Summary: HyperI CI/CD CLI tool — multi-language build, test, and publish automation
|
|
5
5
|
Project-URL: Homepage, https://github.com/hyperi-io/hyperi-ci
|
|
6
6
|
Project-URL: Repository, https://github.com/hyperi-io/hyperi-ci
|
|
@@ -79,6 +79,17 @@ only — those code paths have been removed.
|
|
|
79
79
|
- Semantic-release config that just works
|
|
80
80
|
- A commit hook that catches bad messages before they hit CI
|
|
81
81
|
|
|
82
|
+
## Preventative, Not Detective
|
|
83
|
+
|
|
84
|
+
hyperi-ci is the preventative layer: gitleaks blocks a secret before
|
|
85
|
+
the push, commit validation blocks a bad message before it lands,
|
|
86
|
+
quality gates block a broken build before it merges. GitHub's native
|
|
87
|
+
security features (secret scanning alerts, CodeQL code scanning,
|
|
88
|
+
Dependabot) are the detective layer - they find what already landed,
|
|
89
|
+
or what arrived from upstream in repos hyperi-ci never runs on
|
|
90
|
+
(external forks, mirrors). Run both: hyperi-ci stops you making the
|
|
91
|
+
mess, the GitHub side catches the mess you inherited.
|
|
92
|
+
|
|
82
93
|
## Install
|
|
83
94
|
|
|
84
95
|
```bash
|
|
@@ -104,6 +115,7 @@ This creates `.hyperi-ci.yaml`, `Makefile`, `.github/workflows/ci.yml`,
|
|
|
104
115
|
hyperi-ci check # Quality + test
|
|
105
116
|
hyperi-ci check --quick # Quality only (fast)
|
|
106
117
|
hyperi-ci check --full # Quality + test + build
|
|
118
|
+
hyperi-ci check --strict # Also fail on warn-tier findings (zero warnings)
|
|
107
119
|
|
|
108
120
|
# 3. Commit (hook validates your message format)
|
|
109
121
|
git commit -m "fix: resolve timeout in auth handler"
|
|
@@ -274,6 +286,7 @@ No code changes, no workflow changes.
|
|
|
274
286
|
| `hyperi-ci check` | Pre-push validation (quality + test) |
|
|
275
287
|
| `hyperi-ci check --quick` | Quality only |
|
|
276
288
|
| `hyperi-ci check --full` | Quality + test + build |
|
|
289
|
+
| `hyperi-ci check --strict` | Also fail on warn-tier findings - see [docs/quality-gate.md](docs/quality-gate.md) |
|
|
277
290
|
| `hyperi-ci push` | Push (validate-only — no tag, no publish) |
|
|
278
291
|
| `hyperi-ci push --publish` | Stamp `Publish: true` trailer, push, single-run publish |
|
|
279
292
|
| `hyperi-ci push --bump-patch` | Force +0.0.1 release even with no-bump commits |
|
|
@@ -46,6 +46,17 @@ only — those code paths have been removed.
|
|
|
46
46
|
- Semantic-release config that just works
|
|
47
47
|
- A commit hook that catches bad messages before they hit CI
|
|
48
48
|
|
|
49
|
+
## Preventative, Not Detective
|
|
50
|
+
|
|
51
|
+
hyperi-ci is the preventative layer: gitleaks blocks a secret before
|
|
52
|
+
the push, commit validation blocks a bad message before it lands,
|
|
53
|
+
quality gates block a broken build before it merges. GitHub's native
|
|
54
|
+
security features (secret scanning alerts, CodeQL code scanning,
|
|
55
|
+
Dependabot) are the detective layer - they find what already landed,
|
|
56
|
+
or what arrived from upstream in repos hyperi-ci never runs on
|
|
57
|
+
(external forks, mirrors). Run both: hyperi-ci stops you making the
|
|
58
|
+
mess, the GitHub side catches the mess you inherited.
|
|
59
|
+
|
|
49
60
|
## Install
|
|
50
61
|
|
|
51
62
|
```bash
|
|
@@ -71,6 +82,7 @@ This creates `.hyperi-ci.yaml`, `Makefile`, `.github/workflows/ci.yml`,
|
|
|
71
82
|
hyperi-ci check # Quality + test
|
|
72
83
|
hyperi-ci check --quick # Quality only (fast)
|
|
73
84
|
hyperi-ci check --full # Quality + test + build
|
|
85
|
+
hyperi-ci check --strict # Also fail on warn-tier findings (zero warnings)
|
|
74
86
|
|
|
75
87
|
# 3. Commit (hook validates your message format)
|
|
76
88
|
git commit -m "fix: resolve timeout in auth handler"
|
|
@@ -241,6 +253,7 @@ No code changes, no workflow changes.
|
|
|
241
253
|
| `hyperi-ci check` | Pre-push validation (quality + test) |
|
|
242
254
|
| `hyperi-ci check --quick` | Quality only |
|
|
243
255
|
| `hyperi-ci check --full` | Quality + test + build |
|
|
256
|
+
| `hyperi-ci check --strict` | Also fail on warn-tier findings - see [docs/quality-gate.md](docs/quality-gate.md) |
|
|
244
257
|
| `hyperi-ci push` | Push (validate-only — no tag, no publish) |
|
|
245
258
|
| `hyperi-ci push --publish` | Stamp `Publish: true` trailer, push, single-run publish |
|
|
246
259
|
| `hyperi-ci push --bump-patch` | Force +0.0.1 release even with no-bump commits |
|
hyperi_ci-2.7.3/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.7.3
|
|
@@ -188,7 +188,7 @@ Third-party pinning policy: [dependencies/DEPS-PINNING.md](dependencies/DEPS-PIN
|
|
|
188
188
|
|
|
189
189
|
```
|
|
190
190
|
hyperi-ci run <stage> quality | test | build | publish
|
|
191
|
-
hyperi-ci check [--quick|--full]
|
|
191
|
+
hyperi-ci check [--quick|--full|--strict] pre-push: quality(+test)(+build); --strict fails on warn-tier findings
|
|
192
192
|
hyperi-ci push [--publish] commit + push, opt-in Publish: true trailer
|
|
193
193
|
hyperi-ci release <tag> dispatch a GA/optimised release run
|
|
194
194
|
hyperi-ci publish run the publish stage
|
|
@@ -182,6 +182,7 @@ hyperi-ci run <stage> Run CI stage (setup, quality, test, build, publish)
|
|
|
182
182
|
hyperi-ci check Pre-push validation (quality + test)
|
|
183
183
|
hyperi-ci check --full Pre-push with build (native target only)
|
|
184
184
|
hyperi-ci check --quick Quality checks only
|
|
185
|
+
hyperi-ci check --strict Also fail on warn-tier findings (zero-warnings gate)
|
|
185
186
|
hyperi-ci init Generate project scaffolding
|
|
186
187
|
hyperi-ci detect Show detected language
|
|
187
188
|
hyperi-ci config Show merged configuration
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Project: HyperI CI
|
|
2
|
+
# File: docs/quality-gate.md
|
|
3
|
+
# Purpose: Reference for the quality stage - tools, modes, --strict, skip hatch
|
|
4
|
+
#
|
|
5
|
+
# License: BUSL-1.1 -- HYPERI PTY LIMITED
|
|
6
|
+
# Copyright: (c) 2026 HYPERI PTY LIMITED
|
|
7
|
+
|
|
8
|
+
# Quality gate
|
|
9
|
+
|
|
10
|
+
The quality stage runs a fixed set of tools and decides, per tool, whether a
|
|
11
|
+
finding is fatal. Two cross-language scanners (gitleaks, semgrep) run once at
|
|
12
|
+
the dispatch level; the rest run in the per-language handler. Each tool's
|
|
13
|
+
**effective mode** is resolved from config, an optional strict upgrade, and a
|
|
14
|
+
force-skip escape hatch, in that precedence.
|
|
15
|
+
|
|
16
|
+
Same code runs locally (`hyperi-ci check`) and in CI (`hyperi-ci run quality`).
|
|
17
|
+
The only difference is the local-vs-CI handling of a missing tool (below).
|
|
18
|
+
|
|
19
|
+
## Effective mode - how a tool's fate is decided
|
|
20
|
+
|
|
21
|
+
Bottom line: **skip beats strict beats configured mode.** A force-skip disables
|
|
22
|
+
the tool; otherwise strict upgrades a `warn` tool to `blocking`; otherwise the
|
|
23
|
+
configured mode stands.
|
|
24
|
+
|
|
25
|
+
```mermaid
|
|
26
|
+
flowchart TB
|
|
27
|
+
T["a quality tool"] --> SK{"tool in<br/>HYPERCI_QUALITY_SKIP?"}
|
|
28
|
+
SK -->|yes| D["disabled<br/>(loud CI warning)"]:::skip
|
|
29
|
+
SK -->|no| M["configured mode<br/>quality.<tool> or quality.<lang>.<tool>"]
|
|
30
|
+
M --> ST{"--strict AND<br/>mode is warn?"}
|
|
31
|
+
ST -->|yes| B["blocking"]:::block
|
|
32
|
+
ST -->|no| K["keep configured mode<br/>(blocking / warn / disabled)"]
|
|
33
|
+
classDef skip fill:#D55E00,color:#fff
|
|
34
|
+
classDef block fill:#0072B2,color:#fff
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Resolution lives in `src/hyperi_ci/languages/quality_common.py`
|
|
38
|
+
(`resolve_tool_mode`, `apply_strict`, `is_skipped`) and is shared by the
|
|
39
|
+
per-language handlers and the dispatch-level semgrep module, so the precedence
|
|
40
|
+
is identical everywhere.
|
|
41
|
+
|
|
42
|
+
## Modes
|
|
43
|
+
|
|
44
|
+
| Mode | Finding behaviour |
|
|
45
|
+
|---|---|
|
|
46
|
+
| `blocking` | A finding fails the stage (non-zero exit) |
|
|
47
|
+
| `warn` | A finding prints but does not fail |
|
|
48
|
+
| `disabled` | The tool does not run |
|
|
49
|
+
|
|
50
|
+
Set per project in `.hyperi-ci.yaml` under `quality.<lang>.<tool>` (or
|
|
51
|
+
`quality.<tool>` for the cross-language `gitleaks` / `semgrep`); defaults live in
|
|
52
|
+
`src/hyperi_ci/config/defaults.yaml`.
|
|
53
|
+
|
|
54
|
+
## Tools
|
|
55
|
+
|
|
56
|
+
| Tool | Scope | Where |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| gitleaks | cross-language secret scan | dispatch (`quality/gitleaks.py`) |
|
|
59
|
+
| semgrep | cross-language SAST (`--config auto`) | dispatch (`quality/semgrep.py`) |
|
|
60
|
+
| ruff (lint, format, docstrings) | Python | `languages/python/quality.py` |
|
|
61
|
+
| ty | Python types | Python handler |
|
|
62
|
+
| pip-audit, bandit, vulture | Python | Python handler |
|
|
63
|
+
| clippy, rustfmt, cargo-audit/deny, osv-scanner | Rust | `languages/rust/quality.py` |
|
|
64
|
+
| eslint, prettier, tsc, npm audit, osv-scanner | TypeScript | `languages/typescript/quality.py` |
|
|
65
|
+
| gofmt, govet, golangci-lint, gosec, govulncheck | Go | `languages/golang/quality.py` |
|
|
66
|
+
|
|
67
|
+
semgrep and gitleaks moved to the dispatch level because their rulesets are
|
|
68
|
+
language-agnostic - running them once avoids the drift where only one handler
|
|
69
|
+
passed shared excludes.
|
|
70
|
+
|
|
71
|
+
## --strict - a zero-warnings pre-push gate
|
|
72
|
+
|
|
73
|
+
`hyperi-ci check --strict` treats every `warn`-tier finding as `blocking`, so a
|
|
74
|
+
developer sees - and fixes or explicitly ignores - everything CI would surface
|
|
75
|
+
BEFORE the push, not after. It sets `HYPERCI_QUALITY_STRICT=1`, which
|
|
76
|
+
`apply_strict` reads.
|
|
77
|
+
|
|
78
|
+
`disabled` tools stay off (strict enforces warnings, it does not resurrect a
|
|
79
|
+
tool a project turned off). A tool that is not installed locally (and has no
|
|
80
|
+
`uv` fallback) is still warn-skipped even under `--strict` - strict enforces
|
|
81
|
+
what runs, not what your machine has; CI, where the tools are present, is the
|
|
82
|
+
backstop.
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
hyperi-ci check --strict --quick # strict quality only, no tests
|
|
86
|
+
# -> non-zero if any tool has findings; fix or ignore each, then re-run
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## HYPERCI_QUALITY_SKIP - the rare escape hatch
|
|
90
|
+
|
|
91
|
+
> **Note:** This is an EMERGENCY override, not the normal path. The reviewed,
|
|
92
|
+
> auditable way to silence a tool is the config (`quality.<tool>: disabled` or
|
|
93
|
+
> the `quality.ignore` list).
|
|
94
|
+
|
|
95
|
+
When a tool's false positive halts CI - a semgrep rule misfiring on a
|
|
96
|
+
dependency, an audit advisory with no fix yet - set `HYPERCI_QUALITY_SKIP` to
|
|
97
|
+
the tool name (comma-separated for several) to force it to `disabled` for the
|
|
98
|
+
blocked runs WITHOUT a config commit, then remove it once the real fix lands.
|
|
99
|
+
|
|
100
|
+
A force-skip is logged LOUDLY: a `warn()` line plus, in CI, a real GitHub
|
|
101
|
+
`::warning::` annotation that lands in the run summary (it does not hide inside
|
|
102
|
+
a collapsed log group) - so skipping a security scanner like gitleaks cannot
|
|
103
|
+
pass unnoticed.
|
|
104
|
+
|
|
105
|
+
In CI, set the `HYPERCI_QUALITY_SKIP` repo or org Actions variable; the four
|
|
106
|
+
reusable language workflows pass it through (empty variable = no-op). Only a
|
|
107
|
+
repo admin / org owner can set it.
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# local one-off: skip semgrep for this run
|
|
111
|
+
HYPERCI_QUALITY_SKIP=semgrep hyperi-ci run quality
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Suppressing a specific rule (the reviewed path)
|
|
115
|
+
|
|
116
|
+
To silence one noisy rule permanently, use `quality.ignore` in `.hyperi-ci.yaml`
|
|
117
|
+
- it is committed, diffable, and carries a `reason`:
|
|
118
|
+
|
|
119
|
+
```yaml
|
|
120
|
+
quality:
|
|
121
|
+
ignore:
|
|
122
|
+
- tool: semgrep
|
|
123
|
+
ids:
|
|
124
|
+
- <full.rule.id>
|
|
125
|
+
reason: "why this rule is noise here"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
This is rule-scoped (not a path exclude), so the rest of the tool's coverage
|
|
129
|
+
stays active. `for_tool` in `src/hyperi_ci/quality/ignores.py` feeds these to
|
|
130
|
+
the tool's native ignore flag.
|
|
131
|
+
|
|
132
|
+
## Missing tool - local vs CI
|
|
133
|
+
|
|
134
|
+
A tool that is not installed and has no `uv`/`uvx` fallback:
|
|
135
|
+
|
|
136
|
+
- **In CI** (`CI` env set): a `blocking` tool FAILS - every tool must be
|
|
137
|
+
present, and a silent skip would mask a coverage gap.
|
|
138
|
+
- **Locally**: it warn-skips and carries on, so `hyperi-ci check` still runs
|
|
139
|
+
whatever IS installed and tells you what it skipped.
|
|
140
|
+
|
|
141
|
+
This matches the gitleaks stage's existing behaviour (`is_ci()` in
|
|
142
|
+
`src/hyperi_ci/common.py`).
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
Usage:
|
|
10
10
|
hyperi-ci run <stage> Run a CI stage (setup, quality, test, build, publish)
|
|
11
|
-
hyperi-ci check Pre-push checks (quality + test; --full adds build)
|
|
11
|
+
hyperi-ci check Pre-push checks (quality + test; --full adds build, --strict fails on warnings)
|
|
12
12
|
hyperi-ci push Push with pre-checks (replaces bare git push)
|
|
13
13
|
hyperi-ci init Initialise project (config, Makefile, workflow)
|
|
14
14
|
hyperi-ci detect Detect project language
|
|
@@ -41,6 +41,7 @@ rely on muscle memory. In particular:
|
|
|
41
41
|
from __future__ import annotations
|
|
42
42
|
|
|
43
43
|
import json
|
|
44
|
+
import os
|
|
44
45
|
import sys
|
|
45
46
|
from pathlib import Path
|
|
46
47
|
from typing import Annotated
|
|
@@ -117,10 +118,32 @@ def check(
|
|
|
117
118
|
bool,
|
|
118
119
|
typer.Option("--quick", help="Quality checks only (skip tests)"),
|
|
119
120
|
] = False,
|
|
121
|
+
strict: Annotated[
|
|
122
|
+
bool,
|
|
123
|
+
typer.Option(
|
|
124
|
+
"--strict",
|
|
125
|
+
help=(
|
|
126
|
+
"Fail on warn-tier quality findings (ty, semgrep, "
|
|
127
|
+
"docstrings, ...) too -- a zero-warnings pre-push gate that "
|
|
128
|
+
"surfaces everything CI would show, before the push."
|
|
129
|
+
),
|
|
130
|
+
),
|
|
131
|
+
] = False,
|
|
120
132
|
) -> None:
|
|
121
|
-
"""Run local pre-push checks (quality + test by default).
|
|
133
|
+
"""Run local pre-push checks (quality + test by default).
|
|
134
|
+
|
|
135
|
+
With ``--strict``, warn-tier quality findings (which CI tolerates but
|
|
136
|
+
still prints) are treated as failures, so nothing is carried into a
|
|
137
|
+
push unseen. Fix each, or flag it to ignore if it genuinely should be.
|
|
138
|
+
A tool that is not installed locally (and has no uv fallback) is still
|
|
139
|
+
warn-skipped even under ``--strict`` -- strict enforces what runs, not
|
|
140
|
+
what your machine has; CI, where the tools are present, is the backstop.
|
|
141
|
+
"""
|
|
122
142
|
dir_path = Path(project_dir) if project_dir else None
|
|
123
143
|
|
|
144
|
+
if strict:
|
|
145
|
+
os.environ["HYPERCI_QUALITY_STRICT"] = "1"
|
|
146
|
+
|
|
124
147
|
stages = ["quality"]
|
|
125
148
|
if not quick:
|
|
126
149
|
stages.append("test")
|
|
@@ -239,8 +262,6 @@ def push(
|
|
|
239
262
|
With ``--no-ci``: amends the last commit with ``[skip ci]`` and
|
|
240
263
|
pushes (skips CI altogether).
|
|
241
264
|
"""
|
|
242
|
-
import os
|
|
243
|
-
|
|
244
265
|
from hyperi_ci.push import push as do_push
|
|
245
266
|
|
|
246
267
|
if bump_patch and bump_minor:
|
|
@@ -69,6 +69,7 @@ quality:
|
|
|
69
69
|
enabled: true
|
|
70
70
|
exclude_paths: []
|
|
71
71
|
gitleaks: blocking
|
|
72
|
+
semgrep: warn # Semgrep SAST (cross-language) - runs once at dispatch, like gitleaks
|
|
72
73
|
|
|
73
74
|
# Directories treated as test code (relaxed rules applied)
|
|
74
75
|
# Override per project in .hyperi-ci.yaml
|
|
@@ -79,7 +80,6 @@ quality:
|
|
|
79
80
|
ruff: blocking
|
|
80
81
|
ty: warn # Astral's type checker (OSS, Rust-based, replaces pyright/mypy)
|
|
81
82
|
pyright: disabled # Superseded by ty
|
|
82
|
-
semgrep: warn # Semgrep SAST — auto-config rules for Python
|
|
83
83
|
bandit: disabled # Superseded by ruff S rules
|
|
84
84
|
bandit_exclude_tests: true # Legacy — only used if bandit re-enabled
|
|
85
85
|
pip_audit: blocking
|
|
@@ -114,7 +114,6 @@ quality:
|
|
|
114
114
|
audit: blocking
|
|
115
115
|
audit_level: moderate
|
|
116
116
|
osv_scanner: warn # malicious-package (MAL-*) scan; npm audit is CVE-only
|
|
117
|
-
semgrep: warn # Semgrep SAST — auto-config rules for TypeScript
|
|
118
117
|
test_ignore:
|
|
119
118
|
- "@typescript-eslint/no-explicit-any"
|
|
120
119
|
- "@typescript-eslint/no-non-null-assertion"
|
|
@@ -126,7 +125,6 @@ quality:
|
|
|
126
125
|
golangci_lint: blocking
|
|
127
126
|
gosec: blocking
|
|
128
127
|
govulncheck: warn
|
|
129
|
-
semgrep: warn # Semgrep SAST — auto-config rules for Go
|
|
130
128
|
test_ignore:
|
|
131
129
|
- errcheck
|
|
132
130
|
- gosec
|
|
@@ -138,7 +136,6 @@ quality:
|
|
|
138
136
|
osv_scanner: warn # malicious-package (MAL-*) scan; OSV feed not in RustSec
|
|
139
137
|
deny: warn
|
|
140
138
|
features: all
|
|
141
|
-
semgrep: warn # Semgrep SAST — auto-config rules for Rust
|
|
142
139
|
# Feature-matrix check: catches feature-gating bugs where a module behind
|
|
143
140
|
# feature X uses a crate only declared by feature Y. Without this check,
|
|
144
141
|
# transitive deps from other features mask the bug until a downstream
|
|
@@ -31,7 +31,7 @@ from hyperi_ci.common import (
|
|
|
31
31
|
)
|
|
32
32
|
from hyperi_ci.config import VALID_PROJECT_STATUSES, CIConfig, load_config
|
|
33
33
|
from hyperi_ci.detect import detect_language
|
|
34
|
-
from hyperi_ci.quality import commit_validation, gitleaks
|
|
34
|
+
from hyperi_ci.quality import commit_validation, gitleaks, semgrep
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
class StageRunFn(Protocol):
|
|
@@ -181,6 +181,13 @@ def stage_quality(language: str, config: CIConfig, *, local: bool = False) -> in
|
|
|
181
181
|
if rc != 0:
|
|
182
182
|
return rc
|
|
183
183
|
|
|
184
|
+
# Semgrep SAST is cross-language too (python / go / ts / rust / yaml /
|
|
185
|
+
# ...), so it runs here once rather than inside every language handler.
|
|
186
|
+
with group("Semgrep SAST scanning"):
|
|
187
|
+
rc = semgrep.run(config, language=language)
|
|
188
|
+
if rc != 0:
|
|
189
|
+
return rc
|
|
190
|
+
|
|
184
191
|
# Commit-message validation. In CI this is the dedicated `commit-check`
|
|
185
192
|
# workflow job -- it runs on every merge to main (not just the
|
|
186
193
|
# publish-worthy pushes the run-checks-gated quality job covers) and is
|
|
@@ -11,16 +11,16 @@ from __future__ import annotations
|
|
|
11
11
|
import shutil
|
|
12
12
|
import subprocess
|
|
13
13
|
|
|
14
|
-
from hyperi_ci.common import error, info, success, warn
|
|
14
|
+
from hyperi_ci.common import error, info, is_ci, success, warn
|
|
15
15
|
from hyperi_ci.config import CIConfig
|
|
16
|
-
from hyperi_ci.languages.quality_common import get_test_ignore
|
|
16
|
+
from hyperi_ci.languages.quality_common import get_test_ignore, resolve_tool_mode
|
|
17
17
|
from hyperi_ci.quality.ignores import for_tool, load_ignores
|
|
18
18
|
|
|
19
19
|
_DEFAULT_GO_TEST_IGNORE = ["errcheck", "gosec"]
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
def _get_tool_mode(tool: str, config: CIConfig) -> str:
|
|
23
|
-
return
|
|
23
|
+
return resolve_tool_mode(tool, config, "golang")
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
def _resolve_tool_cmd(cmd: list[str], use_uvx: bool = False) -> list[str]:
|
|
@@ -44,10 +44,15 @@ def _run_tool(
|
|
|
44
44
|
|
|
45
45
|
resolved = _resolve_tool_cmd(cmd, use_uvx=use_uvx)
|
|
46
46
|
if resolved == cmd and not shutil.which(cmd[0]):
|
|
47
|
-
|
|
47
|
+
# A missing tool fails the gate only in CI, where every tool MUST
|
|
48
|
+
# be present -- a silent skip would mask a coverage gap. Locally it
|
|
49
|
+
# is an environment gap, not a quality finding: warn and carry on
|
|
50
|
+
# so `hyperi-ci check` still runs whatever IS installed (matches
|
|
51
|
+
# the gitleaks stage's local-vs-CI handling).
|
|
52
|
+
if mode == "blocking" and is_ci():
|
|
48
53
|
error(f" {tool_name}: not installed (required)")
|
|
49
54
|
return False
|
|
50
|
-
warn(f" {tool_name}: not installed (skipping)")
|
|
55
|
+
warn(f" {tool_name}: not installed (skipping locally)")
|
|
51
56
|
return True
|
|
52
57
|
|
|
53
58
|
result = subprocess.run(resolved, capture_output=True, text=True)
|
|
@@ -131,12 +136,4 @@ def run(config: CIConfig, extra_env: dict[str, str] | None = None) -> int:
|
|
|
131
136
|
if not _run_tool("govulncheck", ["govulncheck", "./..."], mode):
|
|
132
137
|
had_failure = True
|
|
133
138
|
|
|
134
|
-
# Semgrep SAST scanning
|
|
135
|
-
mode = _get_tool_mode("semgrep", config)
|
|
136
|
-
semgrep_cmd = ["semgrep", "scan", "--config", "auto", "--error", "--quiet"]
|
|
137
|
-
for entry in for_tool(ignores, "semgrep"):
|
|
138
|
-
semgrep_cmd.extend(["--exclude-rule", entry.id])
|
|
139
|
-
if not _run_tool("semgrep", semgrep_cmd, mode, use_uvx=True):
|
|
140
|
-
had_failure = True
|
|
141
|
-
|
|
142
139
|
return 1 if had_failure else 0
|