Repository navigation
chore(apb): run the owner dev quality cycle in osb-pr-prepare #265
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
9cbc8d3
chore(apb): run the owner dev quality cycle in osb-pr-prepare
itechmeat df20f31
fix(apb): review what the cycle has not seen, not what was pushed
itechmeat 4e96959
test(storage): seed the forecast trend relative to today
itechmeat e98937d
fix(apb): refuse a CHANGELOG entry on a no-release change
itechmeat 31190e6
test(storage): freeze the clock for the forecast trend census
itechmeat File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| #!/bin/sh | ||
| # Architecture gate: code-ranker in baseline mode. The merge base with | ||
| # origin/<base> is analyzed as the baseline and the committed HEAD as the | ||
| # candidate (both from `git archive`, so untracked files and local tool | ||
| # directories never enter the graph); only violations the branch introduces | ||
| # fail the gate. Pre-existing debt on the base is not this PR's to fix. | ||
| # | ||
| # Exit 0: no new violation. Exit 1: new violations (the output starts with | ||
| # `ARCH-GATE: violations`, followed by code-ranker's fix prompt). Exit 2: the | ||
| # tool itself failed (`ERROR:`), which no code change in the branch can fix. | ||
| [ -n "${BASH_VERSION:-}" ] || exec bash "$0" "$@" | ||
| set -euo pipefail | ||
| . "$(dirname "$0")/lib.sh" | ||
|
|
||
| root=$(repo_root) | ||
| cd "$root" | ||
| load_ctx | ||
| command -v code-ranker >/dev/null 2>&1 || die "code-ranker is not on PATH" | ||
|
|
||
| mb=$(git merge-base "origin/$OSB_BASE" HEAD) || die "no merge base with origin/$OSB_BASE" | ||
| work=$(mktemp -d "${TMPDIR:-/tmp}/osb-arch-gate.XXXXXX") | ||
| trap 'rm -rf "$work"' EXIT | ||
| mkdir -p "$work/base" "$work/head" | ||
| git archive "$mb" | tar -x -C "$work/base" | ||
| git archive HEAD | tar -x -C "$work/head" | ||
|
|
||
| # Explicit plugins so base and head are analyzed with the same languages. | ||
| plugins=(--plugins ts --plugins python --plugins md) | ||
| cd "$work" # code-ranker writes its default HTML viewer under the cwd | ||
| code-ranker report base "${plugins[@]}" --output.mode quiet \ | ||
| --output.json.path "$work/base.json" --output.html.path "$work/base.html" >/dev/null 2>"$work/report.err" || | ||
| die "code-ranker report on the merge base failed: $(cat "$work/report.err")" | ||
|
|
||
| set +e | ||
| code-ranker check head "${plugins[@]}" --baseline "$work/base.json" \ | ||
| --output-format prompt --output.mode summary >"$work/check.out" 2>&1 | ||
| rc=$? | ||
| set -e | ||
|
|
||
| if [ "$rc" -eq 0 ]; then | ||
| cat "$work/check.out" | ||
| echo "ARCH-GATE: pass (no new violation against $mb)" | ||
| exit 0 | ||
| fi | ||
| if grep -q 'new violation(s) vs baseline' "$work/check.out"; then | ||
| echo "ARCH-GATE: violations (new against merge base $mb)" | ||
| sed "s#$work/##g" "$work/check.out" | ||
| exit 1 | ||
| fi | ||
| cat "$work/check.out" | ||
| die "code-ranker check failed without a violation verdict (exit $rc)" |
24 changes: 24 additions & 0 deletions
24
.apb/playbooks/osb-pr-prepare/1.4.0/scripts/check-context.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| #!/bin/sh | ||
| # success_check of `intake`: the recorded PR context is complete and true. | ||
| # apb runs every script through `sh`; re-exec under bash for pipefail. | ||
| [ -n "${BASH_VERSION:-}" ] || exec bash "$0" "$@" | ||
| set -euo pipefail | ||
| . "$(dirname "$0")/lib.sh" | ||
|
|
||
| cd "$(repo_root)" | ||
| load_ctx | ||
|
|
||
| case " $OSB_KINDS " in *" $OSB_KIND "*) ;; *) die "OSB_KIND=$OSB_KIND is not one of: $OSB_KINDS" ;; esac | ||
| case " $OSB_RELEASES " in *" $OSB_RELEASE "*) ;; *) die "OSB_RELEASE=$OSB_RELEASE is not one of: $OSB_RELEASES" ;; esac | ||
|
|
||
| branch=$(git symbolic-ref --quiet --short HEAD) || die "HEAD is detached; the PR needs a branch" | ||
| [ "$branch" = "$OSB_BRANCH" ] || die "checked-out branch $branch differs from OSB_BRANCH=$OSB_BRANCH" | ||
| [ "$branch" != "$OSB_BASE" ] || die "the PR branch is the base branch $OSB_BASE" | ||
| git rev-parse --verify --quiet "origin/$OSB_BASE" >/dev/null || die "origin/$OSB_BASE does not exist; fetch it" | ||
| mb=$(git merge-base "origin/$OSB_BASE" HEAD) || die "no merge base between origin/$OSB_BASE and HEAD" | ||
| git diff --quiet "$mb" HEAD && die "the branch carries no change against origin/$OSB_BASE" | ||
| git diff --quiet || die "tracked files have unstaged changes; the intake commits the implementation first" | ||
| git diff --cached --quiet || die "the index holds staged, uncommitted changes" | ||
|
|
||
| echo "context ok: kind=$OSB_KIND release=$OSB_RELEASE base=$OSB_BASE branch=$OSB_BRANCH merge-base=$mb" | ||
| echo "commits: $(git rev-list --count "$mb"..HEAD), files: $(git diff --name-only "$mb" HEAD | wc -l)" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| #!/bin/sh | ||
| # success_check of `push_pr` (and of the fix nodes that push): the PR recorded | ||
| # in pr.env is open, not merged, targets the base branch, and its head is | ||
| # exactly the local HEAD, which the remote branch also carries. | ||
| [ -n "${BASH_VERSION:-}" ] || exec bash "$0" "$@" | ||
| set -euo pipefail | ||
| . "$(dirname "$0")/lib.sh" | ||
|
|
||
| cd "$(repo_root)" | ||
| load_ctx | ||
| load_pr | ||
|
|
||
| head=$(git rev-parse HEAD) | ||
| git diff --quiet && git diff --cached --quiet || die "uncommitted tracked changes: commit and push them" | ||
| remote=$(git ls-remote origin "refs/heads/$OSB_BRANCH" | cut -f1) | ||
| [ "$remote" = "$head" ] || die "origin/$OSB_BRANCH is '${remote:-absent}', local HEAD is $head: push" | ||
|
|
||
| info=$(gh pr view "$OSB_PR_NUMBER" --json state,headRefOid,baseRefName,headRefName,url \ | ||
| -q '[.state,.headRefOid,.baseRefName,.headRefName,.url]|@tsv') || die "gh pr view $OSB_PR_NUMBER failed" | ||
| IFS=$'\t' read -r state pr_head pr_base pr_branch url <<<"$info" | ||
| [ "$state" = OPEN ] || die "PR #$OSB_PR_NUMBER is $state, expected OPEN (this playbook never merges)" | ||
| [ "$pr_base" = "$OSB_BASE" ] || die "PR #$OSB_PR_NUMBER targets $pr_base, expected $OSB_BASE" | ||
| [ "$pr_branch" = "$OSB_BRANCH" ] || die "PR #$OSB_PR_NUMBER is from $pr_branch, expected $OSB_BRANCH" | ||
| [ "$pr_head" = "$head" ] || die "PR #$OSB_PR_NUMBER head is $pr_head, local HEAD is $head" | ||
| auto=$(gh pr view "$OSB_PR_NUMBER" --json autoMergeRequest -q '.autoMergeRequest != null') | ||
| [ "$auto" = false ] || die "PR #$OSB_PR_NUMBER has auto-merge armed; merging is the operator's call: gh pr merge --disable-auto $OSB_PR_NUMBER" | ||
| echo "PR ok: #$OSB_PR_NUMBER $url open on $OSB_BASE at $head" |
55 changes: 55 additions & 0 deletions
55
.apb/playbooks/osb-pr-prepare/1.4.0/scripts/check-release.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| #!/bin/sh | ||
| # success_check of `docs_version`: the version and CHANGELOG state match what | ||
| # the change kind decided (CLAUDE.md "Versioning"). | ||
| # | ||
| # Release-bearing PR (OSB_RELEASE major|minor|patch): | ||
| # - package.json carries the expected bump of the base version; | ||
| # - the first `## [` heading of CHANGELOG.md is `## [X.Y.Z] - YYYY-MM-DD` | ||
| # (no `[Unreleased]` left above it); | ||
| # - the `[X.Y.Z]: .../compare/vPREV...vX.Y.Z` link reference exists; | ||
| # - `sync-version --check` passes and everything is committed. | ||
| # No-release PR (OSB_RELEASE none): package.json still carries the base version. | ||
| [ -n "${BASH_VERSION:-}" ] || exec bash "$0" "$@" | ||
| set -euo pipefail | ||
| . "$(dirname "$0")/lib.sh" | ||
|
|
||
| cd "$(repo_root)" | ||
| load_ctx | ||
|
|
||
| prev=$(git show "origin/$OSB_BASE:package.json" | json_version) | ||
| now=$(json_version <package.json) | ||
|
|
||
| if [ "$OSB_RELEASE" = none ]; then | ||
| [ "$now" = "$prev" ] || die "kind $OSB_KIND ships no release, but package.json moved $prev -> $now" | ||
| base_first=$(git show "origin/$OSB_BASE:CHANGELOG.md" | grep -m1 -E '^## \[' || true) | ||
| head_first=$(grep -m1 -E '^## \[' CHANGELOG.md || true) | ||
| [ "$head_first" = "$base_first" ] || | ||
| die "kind $OSB_KIND ships no release, but the first CHANGELOG heading moved '$base_first' -> '$head_first'" | ||
| echo "release check ok: no release, version stays $now" | ||
| exit 0 | ||
| fi | ||
|
|
||
| expected=$(python3 - "$prev" "$OSB_RELEASE" <<'PY' | ||
| import sys | ||
| major, minor, patch = (int(p) for p in sys.argv[1].split(".")) | ||
| bump = sys.argv[2] | ||
| if bump == "major": | ||
| major, minor, patch = major + 1, 0, 0 | ||
| elif bump == "minor": | ||
| minor, patch = minor + 1, 0 | ||
| else: | ||
| patch += 1 | ||
| print(f"{major}.{minor}.{patch}") | ||
| PY | ||
| ) | ||
| [ "$now" = "$expected" ] || die "package.json is $now; a $OSB_RELEASE bump of $prev is $expected" | ||
|
|
||
| first=$(grep -m1 -E '^## \[' CHANGELOG.md || true) | ||
| printf '%s\n' "$first" | grep -qE "^## \[$expected\] - [0-9]{4}-[0-9]{2}-[0-9]{2}\$" || | ||
| die "the first CHANGELOG heading is '$first', expected '## [$expected] - <date>'" | ||
| grep -qE "^\[$expected\]: https://github\.com/itechmeat/open-second-brain/compare/v$prev\.\.\.v$expected\$" CHANGELOG.md || | ||
| die "CHANGELOG.md lacks the link reference [$expected]: https://github.com/itechmeat/open-second-brain/compare/v$prev...v$expected" | ||
|
|
||
| bun run scripts/sync-version.ts --check >/dev/null 2>&1 || die "sync-version --check fails: run bun run scripts/sync-version.ts" | ||
| git diff --quiet && git diff --cached --quiet || die "version or CHANGELOG changes are not committed" | ||
| echo "release check ok: $prev -> $expected ($OSB_RELEASE), CHANGELOG heading and link reference present" | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| #!/bin/sh | ||
| # Waits for the PR's checks on the current head with ONE blocking command, | ||
| # `gh pr checks --watch` (no polling loop of our own), then prints the verdict. | ||
| # The checks include CodeRabbit's status, so a green result also means the bot | ||
| # review has finished (or was skipped). | ||
| # | ||
| # The watch runs WITHOUT --fail-fast: the verdict waits until every check has a | ||
| # terminal state. A fast failure (a scan failing in seconds) must not start the | ||
| # fix round while a slow job (windows) is still running, or a late failure of | ||
| # that job needs a second fix round. The red verdict lists every failed check. | ||
| # | ||
| # Before the watch, the script makes sure the CI workflow run for THIS head | ||
| # commit exists. Right after a push, `gh pr checks` can still show the previous | ||
| # commit's finished checks and would return at once with a stale verdict. That | ||
| # registration wait is bounded (REGISTRATION_TRIES x REGISTRATION_SLEEP) and | ||
| # ends as soon as GitHub lists the run. | ||
| # | ||
| # Exit 0 green, 1 red (failed-job logs follow), 2 setup error. | ||
| [ -n "${BASH_VERSION:-}" ] || exec bash "$0" "$@" | ||
| set -euo pipefail | ||
| . "$(dirname "$0")/lib.sh" | ||
|
|
||
| REGISTRATION_TRIES=18 | ||
| REGISTRATION_SLEEP=10 | ||
| WATCH_TIMEOUT=6000 # the windows job alone has taken 45 minutes on a slow runner | ||
| WATCH_INTERVAL=60 # gh's own refresh period while it blocks | ||
| LOG_TAIL=250 | ||
| CI_WORKFLOW=ci.yml | ||
|
|
||
| cd "$(repo_root)" | ||
| load_ctx | ||
| load_pr | ||
|
|
||
| head=$(git rev-parse HEAD) | ||
| pr_head=$(gh pr view "$OSB_PR_NUMBER" --json headRefOid -q .headRefOid) | ||
| [ "$pr_head" = "$head" ] || die "PR #$OSB_PR_NUMBER head $pr_head is not local HEAD $head: push first" | ||
|
|
||
| run_id="" | ||
| for _ in $(seq "$REGISTRATION_TRIES"); do | ||
| run_id=$(gh run list --commit "$head" --workflow "$CI_WORKFLOW" --limit 1 --json databaseId -q '.[0].databaseId // empty') | ||
| [ -n "$run_id" ] && break | ||
| sleep "$REGISTRATION_SLEEP" | ||
| done | ||
| [ -n "$run_id" ] || die "no $CI_WORKFLOW run registered for $head after $((REGISTRATION_TRIES * REGISTRATION_SLEEP))s" | ||
|
|
||
| set +e | ||
| timeout "$WATCH_TIMEOUT" gh pr checks "$OSB_PR_NUMBER" --watch --interval "$WATCH_INTERVAL" >/dev/null 2>&1 | ||
| rc=$? | ||
| set -e | ||
| echo "checks for PR #$OSB_PR_NUMBER at $head (CI run $run_id):" | ||
| gh pr checks "$OSB_PR_NUMBER" 2>&1 || true | ||
|
|
||
| if [ "$rc" -eq 0 ]; then | ||
| echo "CI-GATE: green" | ||
| exit 0 | ||
| fi | ||
| if [ "$rc" -eq 124 ]; then | ||
| echo "CI-GATE: red (checks still pending after ${WATCH_TIMEOUT}s)" | ||
| exit 1 | ||
| fi | ||
| failed=$(gh pr checks "$OSB_PR_NUMBER" --json name,bucket -q '[.[] | select(.bucket == "fail" or .bucket == "cancel") | .name] | join(", ")' 2>/dev/null || true) | ||
| echo "CI-GATE: red (failed: ${failed:-the check list could not be read, see the checks above})" | ||
| # Per failed job, not `--log-failed` on the run: the job logs stay readable | ||
| # even when another workflow run on the same head is still in progress. | ||
| for job in $(gh run view "$run_id" --json jobs -q '.jobs[] | select(.conclusion == "failure") | .databaseId'); do | ||
| echo "--- failed job $job of run $run_id (log tail) ---" | ||
| gh run view --job "$job" --log 2>&1 | tail -n "$LOG_TAIL" || true | ||
| done | ||
| exit 1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| #!/bin/sh | ||
| # Steps 1-3 of the dev quality cycle (skill dev-quality-cycle): OpenCodeReview | ||
| # on the claude-code provider, the read-only Codex review and Claude Code's | ||
| # /security-review, through the skill's own runner `scripts/cycle.sh`. The | ||
| # skill owns the commands, flags, effort levels and failure detection; this | ||
| # script only picks the range and records where the run folder is. | ||
| # | ||
| # Range: what the cycle has not reviewed yet, never what was merely pushed. The | ||
| # cycle_review and final_fix nodes record the head the cycle reviewed in | ||
| # <git-dir>/osb-pr-prepare/cycle-reviewed as "<branch> <sha>". When that record | ||
| # names this branch and its sha is an ancestor of HEAD, the range is <sha>..HEAD; | ||
| # otherwise it is the whole branch against origin/<base>. The runner exits 4 | ||
| # when the range is empty (HEAD already reviewed). | ||
| # | ||
| # The skill lives in $DEV_QUALITY_CYCLE_DIR, default ~/.agents/skills/dev-quality-cycle. | ||
| # | ||
| # Output: the runner's log, then one marker line | ||
| # `CYCLE-RUN: ok|failed|resumable|nothing-new exit=<n> summary=<path>` | ||
| # Exit 0 for every marker: the cycle_review node reads the outputs and decides. | ||
| # Exit 2: setup error (`ERROR:`), which no code change can fix. | ||
| [ -n "${BASH_VERSION:-}" ] || exec bash "$0" "$@" | ||
| set -uo pipefail | ||
| . "$(dirname "$0")/lib.sh" | ||
|
|
||
| cd "$(repo_root)" | ||
| load_ctx | ||
|
|
||
| skill="${DEV_QUALITY_CYCLE_DIR:-$HOME/.agents/skills/dev-quality-cycle}" | ||
| runner="$skill/scripts/cycle.sh" | ||
| [ -x "$runner" ] || die "the dev-quality-cycle skill runner is missing: $runner" | ||
|
|
||
| git rev-parse -q --verify "origin/$OSB_BASE^{commit}" >/dev/null || | ||
| die "origin/$OSB_BASE is unknown: fetch it first" | ||
| range_args=(--base "origin/$OSB_BASE") | ||
| reviewed_file="$CTX_DIR/cycle-reviewed" | ||
| if [ -s "$reviewed_file" ]; then | ||
| read -r reviewed_branch reviewed_sha <"$reviewed_file" | ||
| if [ "$reviewed_branch" = "$OSB_BRANCH" ] && [ -n "${reviewed_sha:-}" ] && | ||
| git merge-base --is-ancestor "$reviewed_sha" HEAD 2>/dev/null; then | ||
| range_args=(--range "$reviewed_sha..HEAD") | ||
| fi | ||
| fi | ||
|
|
||
| # What the change is for: OCR --background-file and the Codex prompt. | ||
| intent="$CTX_DIR/cycle-intent.md" | ||
| { | ||
| printf 'Open Second Brain change of kind %s on branch %s against %s.\n' "$OSB_KIND" "$OSB_BRANCH" "$OSB_BASE" | ||
| printf 'Commits:\n' | ||
| git log --no-merges --format='- %s' "origin/$OSB_BASE..HEAD" | ||
| } >"$intent" | ||
|
|
||
| log="$CTX_DIR/cycle-run.log" | ||
| "$runner" "${range_args[@]}" --context-file "$intent" --exclude 'bun.lock,uv.lock' . >"$log" 2>&1 | ||
| rc=$? | ||
| cat "$log" | ||
| summary=$(sed -n 's/^Summary: //p' "$log" | tail -1) | ||
| case "$rc" in | ||
| 0) status=ok ;; | ||
| 1) status=failed ;; | ||
| 3) status=resumable ;; | ||
| 4) status=nothing-new ;; | ||
| *) die "the cycle runner exited $rc (usage or setup error); see $log" ;; | ||
| esac | ||
| echo "CYCLE-RUN: $status exit=$rc summary=${summary:-none}" | ||
| exit 0 |
43 changes: 43 additions & 0 deletions
43
.apb/playbooks/osb-pr-prepare/1.4.0/scripts/final-gates.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| #!/bin/sh | ||
| # Final gates before the push: the QA gates (qa-gates.sh) and the | ||
| # architecture gate (arch-gate.sh) again, after the OpenCodeReview pass may | ||
| # have committed fixes. When HEAD is still the commit the QA gates last | ||
| # passed on, nothing changed since the green QA and architecture gates (the | ||
| # architecture gate runs after the QA gates and any fix it needed moves | ||
| # HEAD), so the re-run is skipped. | ||
| # | ||
| # Exit 0: both green, or skipped (`FINAL-GATES: pass`). Exit 1: a red gate | ||
| # (`FINAL-GATES: red`, followed by the markers and output of the red gates). | ||
| # Exit 2: a setup or tool error (`ERROR:`), which no code change can fix. | ||
| [ -n "${BASH_VERSION:-}" ] || exec bash "$0" "$@" | ||
| set -uo pipefail | ||
| here=$(dirname "$0") | ||
| . "$here/lib.sh" | ||
|
|
||
| cd "$(repo_root)" | ||
| load_ctx | ||
|
|
||
| head=$(git rev-parse HEAD) | ||
| green="$CTX_DIR/qa-green-head" | ||
| if [ -f "$green" ] && [ "$(cat "$green")" = "$head" ]; then | ||
| echo "FINAL-GATES: pass (HEAD $head unchanged since the green QA and architecture gates)" | ||
| exit 0 | ||
| fi | ||
|
|
||
| qa_out=$(sh "$here/qa-gates.sh" 2>&1) | ||
| qa_rc=$? | ||
| arch_out=$(sh "$here/arch-gate.sh" 2>&1) | ||
| arch_rc=$? | ||
|
|
||
| if [ "$qa_rc" -eq 0 ] && [ "$arch_rc" -eq 0 ]; then | ||
| printf '%s\n%s\n' "$qa_out" "$arch_out" | ||
| echo "FINAL-GATES: pass (QA and architecture gates green at $head)" | ||
| exit 0 | ||
| fi | ||
| if [ "$qa_rc" -eq 2 ] || [ "$arch_rc" -eq 2 ]; then | ||
| printf '%s\n%s\n' "$qa_out" "$arch_out" | ||
| die "a gate could not run (qa exit $qa_rc, arch exit $arch_rc)" | ||
| fi | ||
| echo "FINAL-GATES: red (qa exit $qa_rc, arch exit $arch_rc)" | ||
| printf '%s\n%s\n' "$qa_out" "$arch_out" | ||
| exit 1 |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.