diff --git a/.github/ci-gate-matrix.yml b/.github/ci-gate-matrix.yml index bf9b2107..07909c2f 100644 --- a/.github/ci-gate-matrix.yml +++ b/.github/ci-gate-matrix.yml @@ -177,10 +177,16 @@ gates: workflow: ci-quality-gates.yml job: quality-gates execution: explicit + # Points at the inventory guard rather than at one suite. The 87 architecture rules used to be + # 74-in-one-class plus a scattered remainder, so naming CleanArchitectureTest.java named most of + # them and silently omitted the rest; after the split (BOOT-012) it would have named a fifth of + # them. ArchRuleDiscoveryContractTest pins every rule in the package by name and fails if one is + # declared where ArchUnit cannot discover it, which is the property this gate actually exists to + # protect. - id: architecture-contract-test release_blocking: true mechanism: contract-test - ref: app-bootstrap/src/test/java/dev/caskeleton/bootstrap/architecture/CleanArchitectureTest.java + ref: app-bootstrap/src/test/java/dev/caskeleton/bootstrap/architecture/ArchRuleDiscoveryContractTest.java workflow: ci-quality-gates.yml job: quality-gates execution: check diff --git a/.github/scripts/verify-gradle-wrapper.sh b/.github/scripts/verify-gradle-wrapper.sh index 3a1ee42a..ac5c5aa9 100755 --- a/.github/scripts/verify-gradle-wrapper.sh +++ b/.github/scripts/verify-gradle-wrapper.sh @@ -16,34 +16,34 @@ readonly EXPECTED_GUARDED_GRADLE_IF="\${{ always() && steps.gradle-wrapper-valid # Replace this entire sorted array in the same reviewed change. Never refresh a single digest # merely to make this verifier pass. readonly EXPECTED_WORKFLOW_LOCK=( - 'e27d981f43815294e47470e51f61671ee7047794e2a638d1b71a91ee957a18c6 .github/workflows/ci-quality-gates.yml' + 'eb85872c4b2f59b3d80b4d558a200f47c2e1fdde97c1a1781dfc26fa3771b8a8 .github/workflows/ci-quality-gates.yml' '59de260a70c2c0a0d686d97035a189dc0567395977dfa18758f1a2d89d15a00d .github/workflows/dependency-vulnerability.yml' '1b3220c922f954500f727c6a799b24e4962915845b9248e8e496e5050e829f28 .github/workflows/fileserver-nightly.yml' - '26812e16b8d6e4472543ddd49c7b16ee6b7697834ddbb653fa0424befd71c544 .github/workflows/fileserver-pr.yml' + '1c6f72c3914e3fb99e6dd93274ded1c784014ed6ff6cea2df8575e73ff46345a .github/workflows/fileserver-pr.yml' '86a240c4ce7d0d293616e30de30ed77bcfdc700fedb8916f083eda9567099096 .github/workflows/fileserver-release.yml' - '58e28f3358d794ca08f4aa8df4516e03f50a9ee58488b3f0d2619998e069ef14 .github/workflows/httpclient-contract.yml' + '06c762637998ef394da6cbec907e318e024f8119ccdec7b286f142e677e6d748 .github/workflows/httpclient-contract.yml' '823bc346e58a58b2c0814cd1e3e55ec90d360c138419ec3d8f05deb59c62c7eb .github/workflows/httpclient-nightly.yml' 'ad84000efc438ee7439517b8f85819e62b13dab0aa4f94066c2905060f3bb581 .github/workflows/httpclient-release.yml' - '3be84c9f15fa3b2ac5a085f8d725ec6d05e7007ae0b433da9e79b3bf340d57ea .github/workflows/jpa-next-hibernate8.yml' - 'a2b74bfb3af12d6d03cd2ea8a5e48490dd131afb89b79694d498c5798387ac53 .github/workflows/jpa-next-jpa4.yml' - 'cd955ef4af895df477896dad9577810f010b2beea8570b09b008f9e94e928bd0 .github/workflows/jpa-next-postgresql19.yml' + '13a284e11d7ea66b70707b038a7c28495cbf88e66454a88ec2caf8e8f95550ab .github/workflows/jpa-next-hibernate8.yml' + 'cf45357dc27c1d6e7fa4462c76f716bc44352fd8d59cc6829708a2c345f8ffda .github/workflows/jpa-next-jpa4.yml' + 'b0efe44efd94b3a10f86e3a63278d8946d0fc65d5f011bb3759bd74c31d5f6e7 .github/workflows/jpa-next-postgresql19.yml' '21e065880ef5d4c4ff973f52d8107ef08398ebaf9518ec6b2fd82d49c5d822c6 .github/workflows/jpa-nightly.yml' - '04851f44ba94533bfbc8fabe2b3a2b408726a9996e86ed3864986d1499d16b50 .github/workflows/jpa-pr.yml' + '0a1e8e71fa8940c1517a3410e79c7bdf7d52134686a09fbf25bdcf14ab77f9f0 .github/workflows/jpa-pr.yml' '59cb3a0ffc687a15eefe96bc5e3a70d42be78e1cc85d2e7f7880dac6124ca4c7 .github/workflows/jpa-r2-evidence.yml' - 'cf4f80134197dd6d7dc177f0d21294a6b9ffe8709be67d05089f7ff0ce6c9429 .github/workflows/jpa-release.yml' + 'fb9bd883106004ad1bb2471ce5ce885ca68cc9db9bf5e6ee1f6ac3c0ccc54087 .github/workflows/jpa-release.yml' '5be7e931db749029d89787da042d6d7cf8e683d60698bd8a2993c29db26355fb .github/workflows/link-check.yml' '8adafc59a2d87a6c65ef94b4726d7d036ac81b150ed3d301578308e6f9a3523f .github/workflows/messaging-certification.yml' - '4e4ccfa267ecd63b9369803d49f2dbdb2fa899517ad4cf23ab11d29104557a91 .github/workflows/notification-platform.yml' - '64245586cd5936f1a5647b57f2cd9acd316f96fd75f713b1890decb812e7d5fe .github/workflows/object-storage-qualification.yml' - 'cbc104ea486c746229895e804e3be7716e056a02cce0588c537bce9f442f8b38 .github/workflows/redis-sdk-topology.yml' + '34a918d48426d11a0598ef3ba36ba5e6b88150705a3baafbe8b3f36d0b0e25b7 .github/workflows/notification-platform.yml' + '9f00644e2d6835981c9041a8c37bf144dffde50d0ca78b781dc7558ab0e85c26 .github/workflows/object-storage-qualification.yml' + 'd8c099119df05308ffc1343569124e80c6abfad6823581ba9d9b6e187884692b .github/workflows/redis-sdk-topology.yml' '89fb84532d542f7951e11cf2925425ea84b7ef9cc22f4587f1d2cfd99c481f5f .github/workflows/web-advanced-nightly.yml' 'a3d01b73831f1f77a09edfe883e32cd63c8dc8c79b022faf7fec7bdd08c6e4db .github/workflows/web-advanced-release.yml' '4198ce8215097ae9342167c4985455bbe6e56956a3be05bee33428381cad638d .github/workflows/web-nightly.yml' 'b07b92c43e94f674fe6c851603dd27bbed72894274f031b95c3d6e2b256650bd .github/workflows/web-pr.yml' - 'a82f3eacee01165cf9c0767657a584a2524d7bb751f1d567a696241ea44cb3b6 .github/workflows/web-release.yml' + '21e35b5cfdd7878b74a2dd8efdac20732dfba261529da8d066ec627251aa73f7 .github/workflows/web-release.yml' 'f37b2b2598687679a3fb0ae9ea2b50cd5d84a64de7e5852f38a3e5b93bf76e4d .github/workflows/websocket-advanced-nightly.yml' '5643fe9c9d27d9e6f5ac30a731e77a962b68bed2961566e2e64cdb3991ef2350 .github/workflows/websocket-pr.yml' - 'c9fabc17fe755f9f0ee54007e48357fec9493a89ecf67fa2878f4dbc23478f30 .github/workflows/websocket-release.yml' + '32232df17da7ae3d2257eda3953eaeb1a774752ecbecb6fb15b921702cf7c434 .github/workflows/websocket-release.yml' ) readonly EXPECTED_WRAPPER_PROPERTIES=( 'distributionBase=GRADLE_USER_HOME' diff --git a/.github/workflows/ci-quality-gates.yml b/.github/workflows/ci-quality-gates.yml index df776fce..55724eab 100644 --- a/.github/workflows/ci-quality-gates.yml +++ b/.github/workflows/ci-quality-gates.yml @@ -48,6 +48,13 @@ jobs: - name: Check quality, public paths, and dependency locks working-directory: src run: ./gradlew check verifyPublicPathSnapshot verifyDependencyLocks --warning-mode=fail --no-daemon --stacktrace + # build-logic is an included build: its own suite is not reachable from the root project's + # `check`, so the convention plugins every leaf applies shipped untested in CI. Kept as its + # own step rather than folded into the aggregate invocation above, which + # ConditionalTransportQualificationContractTest asserts on byte-for-byte. + - name: Test the build-logic convention plugins + working-directory: src + run: ./gradlew -p build-logic test --no-daemon --stacktrace # Named as its own step because nothing else runs it: `check` does not depend on # graphqlStableTest, so the lane's required-class guard — the check that its module-boundary # suite has not silently stopped being discovered — protected nothing in CI. A separate step @@ -181,6 +188,9 @@ jobs: - jpa-candidate-evidence if: always() runs-on: ubuntu-latest + permissions: + contents: read + checks: read steps: - name: Require every current blocking job to succeed env: @@ -203,3 +213,56 @@ jobs: fi done echo "release-gate: all current blocking quality jobs succeeded." + + # `needs` cannot reach another workflow, so every gate .github/ci-gate-matrix.yml marks + # release_blocking outside this file was invisible here: the field was read by nothing but an + # enum check in verify-gate-matrix.sh. filesystem-vulnerability-scan + # (dependency-vulnerability.yml::trivy-fs) is release_blocking: true and blocks on + # CRITICAL/HIGH and on the CISA KEV catalogue — it could be red while this job reported green + # and nothing in the repository joined the two. + # + # dependency-vulnerability.yml answers the same pull_request and push-to-main triggers as this + # workflow and trivy-fs carries no `if:` guard, so its check run always exists for this SHA. + # That is what makes it requirable by result rather than by scheduling luck. Only `success` + # passes: a skipped or cancelled security scan is not a scan. + # + # The other release_blocking gates outside this file (object-storage-qualification.yml, + # httpclient-release.yml, messaging-certification.yml) run on triggers this job does not + # share, so they cannot be required here without changing when they run. That is left as a + # stated gap rather than a silently different one. + - name: Require the cross-workflow release-blocking checks to have succeeded + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + COMMIT_SHA: ${{ github.sha }} + REQUIRED_CHECKS: trivy-fs + run: | + set -euo pipefail + deadline=$(( $(date +%s) + 1800 )) + for required in ${REQUIRED_CHECKS}; do + while :; do + result="$( + gh api \ + "repos/${GH_REPO}/commits/${COMMIT_SHA}/check-runs?check_name=${required}&per_page=100" \ + --jq '[.check_runs[]] | sort_by(.started_at) | last + | if . == null then "absent none" + else "\(.status) \(.conclusion // "none")" end' + )" + check_status="${result%% *}" + check_conclusion="${result##* }" + if [[ "${check_status}" == "completed" ]]; then + break + fi + if (( $(date +%s) >= deadline )); then + echo "::error::release-gate: release-blocking check ${required} reported no result for ${COMMIT_SHA} (status ${check_status})" + exit 1 + fi + echo "release-gate: waiting for ${required} (status ${check_status})" + sleep 30 + done + if [[ "${check_conclusion}" != "success" ]]; then + echo "::error::release-gate: release-blocking check ${required} concluded ${check_conclusion}" + exit 1 + fi + echo "release-gate: ${required} concluded success." + done diff --git a/.github/workflows/fileserver-pr.yml b/.github/workflows/fileserver-pr.yml index 29ee26d6..57990a51 100644 --- a/.github/workflows/fileserver-pr.yml +++ b/.github/workflows/fileserver-pr.yml @@ -23,8 +23,9 @@ on: - 'docs/registries/env-keys.yaml' - 'src/Dockerfile' - 'docker-compose.yml' - - 'infra/nginx/**' - - 'infra/k8s/**' + - 'infra/fileserver/nginx/**' + - 'infra/fileserver/kubernetes/**' + - 'infra/fileserver/nfs/**' - '.github/workflows/fileserver-pr.yml' permissions: @@ -57,7 +58,7 @@ jobs: run: >- ./gradlew :application-core:test - :app-bootstrap:test --tests '*CleanArchitectureTest' --tests '*Fileserver*' + :app-bootstrap:test --tests 'dev.caskeleton.bootstrap.architecture.*' --tests '*Fileserver*' --no-daemon --stacktrace diff --git a/.github/workflows/httpclient-contract.yml b/.github/workflows/httpclient-contract.yml index ea19dbe7..00d07994 100644 --- a/.github/workflows/httpclient-contract.yml +++ b/.github/workflows/httpclient-contract.yml @@ -127,6 +127,6 @@ jobs: working-directory: src run: >- ./gradlew - :app-bootstrap:test --tests '*httpclient*' --tests '*CleanArchitectureTest' + :app-bootstrap:test --tests '*httpclient*' --tests 'dev.caskeleton.bootstrap.architecture.*' --no-daemon --stacktrace diff --git a/.github/workflows/jpa-next-hibernate8.yml b/.github/workflows/jpa-next-hibernate8.yml index 7d102b86..c8d3ac6b 100644 --- a/.github/workflows/jpa-next-hibernate8.yml +++ b/.github/workflows/jpa-next-hibernate8.yml @@ -19,7 +19,6 @@ jobs: hibernate8-compatibility: runs-on: ubuntu-latest timeout-minutes: 45 - continue-on-error: true steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # actions/checkout@v4.2.2 - name: Validate Gradle wrapper @@ -35,6 +34,7 @@ jobs: src/**/gradle-wrapper.properties src/**/gradle.lockfile - name: Report Hibernate ORM 8 compatibility + id: compatibility-probe working-directory: src run: >- ./gradlew @@ -43,12 +43,15 @@ jobs: --stacktrace - name: Record what this lane did and did not execute if: always() + env: + PROBE_OUTCOME: ${{ steps.compatibility-probe.outcome }} run: | mkdir -p compatibility-evidence { echo "target=Hibernate 8" echo "target-coordinate=org.hibernate.orm:hibernate-core:8.x" echo "status=NOT_EXECUTABLE" + echo "probe-result=${PROBE_OUTCOME}" echo "reason=Hibernate 8 is not resolvable from this build, so nothing has been compiled or run against it" echo "what-ran=the current runtime's own policy and lane-definition tests" echo "sha=${{ github.sha }}" diff --git a/.github/workflows/jpa-next-jpa4.yml b/.github/workflows/jpa-next-jpa4.yml index 9ed0eb43..52c4a52a 100644 --- a/.github/workflows/jpa-next-jpa4.yml +++ b/.github/workflows/jpa-next-jpa4.yml @@ -19,7 +19,6 @@ jobs: jpa4-compatibility: runs-on: ubuntu-latest timeout-minutes: 45 - continue-on-error: true steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # actions/checkout@v4.2.2 - name: Validate Gradle wrapper @@ -35,6 +34,7 @@ jobs: src/**/gradle-wrapper.properties src/**/gradle.lockfile - name: Report Jakarta Persistence 4.0 compatibility + id: compatibility-probe working-directory: src run: >- ./gradlew @@ -43,12 +43,15 @@ jobs: --stacktrace - name: Record what this lane did and did not execute if: always() + env: + PROBE_OUTCOME: ${{ steps.compatibility-probe.outcome }} run: | mkdir -p compatibility-evidence { echo "target=Jakarta Persistence 4" echo "target-coordinate=jakarta.persistence:jakarta.persistence-api:4.x" echo "status=NOT_EXECUTABLE" + echo "probe-result=${PROBE_OUTCOME}" echo "reason=the JPA 4 API is not on any configuration this build resolves, so nothing has been compiled against it" echo "what-ran=the current runtime's own policy and lane-definition tests" echo "sha=${{ github.sha }}" diff --git a/.github/workflows/jpa-next-postgresql19.yml b/.github/workflows/jpa-next-postgresql19.yml index 236d82ab..32e40e47 100644 --- a/.github/workflows/jpa-next-postgresql19.yml +++ b/.github/workflows/jpa-next-postgresql19.yml @@ -25,7 +25,6 @@ jobs: postgresql19-compatibility: runs-on: ubuntu-latest timeout-minutes: 60 - continue-on-error: true steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # actions/checkout@v4.2.2 - name: Validate Gradle wrapper @@ -41,6 +40,7 @@ jobs: src/**/gradle-wrapper.properties src/**/gradle.lockfile - name: Report PostgreSQL 19 compatibility + id: compatibility-probe working-directory: src run: >- ./gradlew @@ -49,12 +49,15 @@ jobs: --stacktrace - name: Record what this lane did and did not execute if: always() + env: + PROBE_OUTCOME: ${{ steps.compatibility-probe.outcome }} run: | mkdir -p compatibility-evidence { echo "target=PostgreSQL 19" echo "target-coordinate=postgres:19-alpine" echo "status=NOT_EXECUTABLE" + echo "probe-result=${PROBE_OUTCOME}" echo "reason=no PostgreSQL 19 image is published yet, so no container of that major has ever been started by this lane" echo "what-ran=the current runtime's own policy and lane-definition tests" echo "sha=${{ github.sha }}" diff --git a/.github/workflows/jpa-pr.yml b/.github/workflows/jpa-pr.yml index 8cf45400..5671b719 100644 --- a/.github/workflows/jpa-pr.yml +++ b/.github/workflows/jpa-pr.yml @@ -51,7 +51,7 @@ jobs: run: >- ./gradlew :adapter:outbound:persistence-jpa:test - :app-bootstrap:test --tests '*CleanArchitectureTest' + :app-bootstrap:test --tests 'dev.caskeleton.bootstrap.architecture.*' verifyCleanArchitectureDependencies verifyOneTypePerFile --no-daemon diff --git a/.github/workflows/jpa-release.yml b/.github/workflows/jpa-release.yml index e1c3ebbc..3caef645 100644 --- a/.github/workflows/jpa-release.yml +++ b/.github/workflows/jpa-release.yml @@ -144,7 +144,7 @@ jobs: ./gradlew verifyCleanArchitectureDependencies verifyOneTypePerFile - :app-bootstrap:test --tests '*CleanArchitectureTest' + :app-bootstrap:test --tests 'dev.caskeleton.bootstrap.architecture.*' :adapter:outbound:persistence-jpa:test --tests '*JpaReleaseManifestTest' --no-daemon --stacktrace diff --git a/.github/workflows/notification-platform.yml b/.github/workflows/notification-platform.yml index 5bd03e15..ade16a1a 100644 --- a/.github/workflows/notification-platform.yml +++ b/.github/workflows/notification-platform.yml @@ -90,7 +90,7 @@ jobs: working-directory: src run: | ./gradlew verifyCleanArchitectureDependencies --console=plain - ./gradlew :app-bootstrap:test --tests '*CleanArchitectureTest' --tests '*NotificationArchitectureTest' --console=plain + ./gradlew :app-bootstrap:test --tests 'dev.caskeleton.bootstrap.architecture.*' --console=plain - name: Configuration surface working-directory: src run: | diff --git a/.github/workflows/object-storage-qualification.yml b/.github/workflows/object-storage-qualification.yml index 4f256d1c..5198e620 100644 --- a/.github/workflows/object-storage-qualification.yml +++ b/.github/workflows/object-storage-qualification.yml @@ -11,6 +11,17 @@ on: required: true default: false type: boolean + # AwsS3DirectTransferQualificationTest requires a second, separate authority + # (OBJECT_STORAGE_AWS_DIRECT_MUTATION_ENABLED) before the direct-transfer lane may run, and + # the job never supplied it. objectStorageAwsQualificationTest is a strict qualification task + # that requires both of its classes, so the lane could not be run to a pass from any input: + # dispatching it always failed on the missing variable. The authority now exists as its own + # input rather than as a constant, which is what "separate" was supposed to mean. + run_protected_aws_direct_mutation: + description: Also authorize the direct-transfer mutation lane against the sandbox bucket + required: true + default: false + type: boolean permissions: contents: read @@ -81,11 +92,15 @@ jobs: run: ./gradlew :adapter:outbound:objectstorage:objectStorageMinioFaultTest --no-daemon --stacktrace aws-managed-common-subset: - if: github.event_name == 'workflow_dispatch' && inputs.run_protected_aws + if: >- + github.event_name == 'workflow_dispatch' + && inputs.run_protected_aws + && inputs.run_protected_aws_direct_mutation environment: object-storage-aws-qualification runs-on: ubuntu-latest env: OBJECT_STORAGE_AWS_QUALIFICATION_ENABLED: "true" + OBJECT_STORAGE_AWS_DIRECT_MUTATION_ENABLED: ${{ inputs.run_protected_aws_direct_mutation }} OBJECT_STORAGE_AWS_BUCKET: ${{ secrets.OBJECT_STORAGE_AWS_BUCKET }} OBJECT_STORAGE_AWS_REGION: ${{ secrets.OBJECT_STORAGE_AWS_REGION }} OBJECT_STORAGE_AWS_EXPECTED_OWNER: ${{ secrets.OBJECT_STORAGE_AWS_EXPECTED_OWNER }} diff --git a/.github/workflows/redis-sdk-topology.yml b/.github/workflows/redis-sdk-topology.yml index 021a1cd1..8d358ce3 100644 --- a/.github/workflows/redis-sdk-topology.yml +++ b/.github/workflows/redis-sdk-topology.yml @@ -135,8 +135,19 @@ jobs: set -euo pipefail # The tag says 7.4; the digest says which 7.4. Evidence that names only the tag cannot be # reproduced once the tag moves. + # + # This used to end in `|| echo 'unresolved'`, which absorbed the failure that `set -e` was + # there to catch: the manifest below recorded `image_digest=unresolved`, the upload + # satisfied `if-no-files-found: error`, and the lane went green holding exactly the + # artifact this workflow's header calls "not evidence". Compose pulls the image in the + # step before this one, so RepoDigests is populated; if it is not, the run has nothing to + # certify and says so. digest="$(docker image inspect --format '{{index .RepoDigests 0}}' \ - "redis:${{ matrix.redis_version }}" 2>/dev/null || echo 'unresolved')" + "redis:${{ matrix.redis_version }}")" + if [[ -z "$digest" ]]; then + echo "::error::no repository digest for redis:${{ matrix.redis_version }}; this run cannot say which image produced its evidence" + exit 1 + fi printf 'digest=%s\n' "$digest" >> "$GITHUB_OUTPUT" - name: Run the topology contracts working-directory: src diff --git a/.github/workflows/web-release.yml b/.github/workflows/web-release.yml index 9d9545a5..0e79109c 100644 --- a/.github/workflows/web-release.yml +++ b/.github/workflows/web-release.yml @@ -11,6 +11,13 @@ on: workflow_dispatch: push: tags: + # 'v*' is this repository's release tag, and jpa-release, httpclient-release and + # web-advanced-release already fire on it. While this workflow answered only to + # 'web-v*', tagging 'v1.2.3' ran the Advanced gate and skipped this Stable one, so a + # release could choose which gate it cleared. Both patterns are listed: the namespaced + # tag keeps working for a component-only release, and the repository tag can no longer + # bypass the gate. + - 'v*' - 'web-v*' permissions: @@ -47,7 +54,7 @@ jobs: verifyCleanArchitectureDependencies verifyPublicPathSnapshot verifyEnvKeys - :app-bootstrap:test --tests '*CleanArchitectureTest' + :app-bootstrap:test --tests 'dev.caskeleton.bootstrap.architecture.*' --no-daemon --stacktrace - name: Publish the release evidence diff --git a/.github/workflows/websocket-release.yml b/.github/workflows/websocket-release.yml index 783329b0..93938663 100644 --- a/.github/workflows/websocket-release.yml +++ b/.github/workflows/websocket-release.yml @@ -8,6 +8,13 @@ on: workflow_dispatch: push: tags: + # 'v*' is this repository's release tag, and jpa-release, httpclient-release and + # web-advanced-release already fire on it. While this workflow answered only to + # 'websocket-v*', tagging 'v1.2.3' ran the Advanced gate and skipped this Stable one, so a + # release could choose which gate it cleared. Both patterns are listed: the namespaced + # tag keeps working for a component-only release, and the repository tag can no longer + # bypass the gate. + - 'v*' - 'websocket-v*' permissions: @@ -44,7 +51,7 @@ jobs: :adapter:inbound:websocket:websocketNginxTest :adapter:inbound:websocket:websocketTransportQualificationTest verifyCleanArchitectureDependencies - :app-bootstrap:test --tests '*CleanArchitectureTest' + :app-bootstrap:test --tests 'dev.caskeleton.bootstrap.architecture.*' --no-daemon --stacktrace - name: Publish the release evidence diff --git a/CLAUDE.md b/CLAUDE.md index af443259..0e306630 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -106,7 +106,7 @@ Architecture-wide commands: ```bash ./gradlew verifyCleanArchitectureDependencies --console=plain -./gradlew :app-bootstrap:test --tests '*CleanArchitectureTest' --console=plain +./gradlew :app-bootstrap:test --tests 'dev.caskeleton.bootstrap.architecture.*' --console=plain ./gradlew verifyPublicPathSnapshot --console=plain ./gradlew verifyEnvKeys --console=plain ```