docs: CI integration recipe for the exit-code PR gate - #17
Conversation
Reviewer's GuideAdds bilingual, copy-paste GitHub Actions guidance for using Flow diagram for PR gate exit-code decisionsflowchart TD
A[Run euthyna audit] --> B{Exit code}
B -->|0| C[Merge freely]
B -->|10| D[Human reviews report before merging]
B -->|1| E[Fix workflow usage]
B -->|2| F[Never merge; fix measurement failure]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 2 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="docs/ci-integration.md" line_range="53-63" />
<code_context>
+
+```yaml
+ - name: 变更面审计(删除代码来源 + 依赖锁定版本)
+ run: |
+ npx --yes euthyna@latest audit --base "origin/${{ github.base_ref }}" --head HEAD
+ continue-on-error: true
+ id: audit
+ - name: 执行契约(10 = 留给人工审阅,其余非零失败)
+ if: always()
+ run: |
+ code=${{ steps.audit.outcome == 'success' && 0 || 1 }}
+ if [ "$code" -eq 0 ]; then exit 0; fi
+ echo "euthyna audit 未测成干净(或发现了 security 分类的历史);见上一步。" >&2
+ exit 1
+```
+
</code_context>
<issue_to_address>
**issue (bug_risk):** The optional two-step workflow cannot distinguish exit code `10` from exit codes `1` and `2`: every non-successful audit outcome is converted to `1`, so the enforcement step fails for flagged audits as well as measurement or usage errors. This contradicts the stated purpose of allowing `10` not to block merges.
**Triggers:** When a repository copies the two-step variant intending security-classified findings (`10`) to remain mergeable.
**Suggested fix:** Capture the audit process exit code explicitly, for example by writing `$?` to `GITHUB_OUTPUT` before enabling `continue-on-error`, then allow only code `10` and fail for `1` or `2`.
</issue_to_address>
### Comment 2
<location path="docs/ci-integration.md" line_range="75-84" />
<code_context>
+ id: audit
+ - name: 执行契约(10 = 留给人工审阅,其余非零失败)
+ if: always()
+ run: |
+ code=${{ steps.audit.outcome == 'success' && 0 || 1 }}
+ if [ "$code" -eq 0 ]; then exit 0; fi
+ echo "euthyna audit 未测成干净(或发现了 security 分类的历史);见上一步。" >&2
+ exit 1
+```
+
+`ponytail:` 两步版用 shell 重述了一遍退出码,把 `10` 和 `2` 混在一起;一步版才是诚实的
+门禁。只有当 `10` 不该挡合并时才用两步版。
+
+## 把报告挂到 PR 上
+
+运行会把人类可读的报告打进步骤日志。要作为附件挂到 PR 上:
+
+```yaml
+ - name: 变更面审计
+ run: |
+ npx --yes euthyna@latest audit --base "origin/${{ github.base_ref }}" --head HEAD \
+ | tee audit-report.txt
+ continue-on-error: true
+ id: audit
+ - uses: actions/upload-artifact@v4
+ if: always()
+ with:
+ name: euthyna-audit-report
+ path: audit-report.txt
+```
+
</code_context>
<issue_to_address>
**issue (broader_impact):** The artifact-upload recipe pipes `euthyna audit` into `tee` without enabling `pipefail`, so the shell reports `tee`'s successful status instead of the audit's exit code. A usage error, unmeasured result, or flagged result therefore makes this copied workflow step succeed and can silently turn the purported PR gate green.
**Triggers:** When this artifact snippet is used as the audit step in a gating workflow.
**Suggested fix:** Enable `set -o pipefail` before the pipeline, or capture the audit status explicitly while still writing the report file.
</issue_to_address>Sourcery assessment
Approval pending. 2 findings to address first.
Blocking findings: docs/ci-integration.md:63, docs/ci-integration.md:84
| run: | | ||
| npx --yes euthyna@latest audit --base "origin/${{ github.base_ref }}" --head HEAD | ||
| continue-on-error: true | ||
| id: audit | ||
| - name: Enforce the contract (10 = review, anything else non-zero fails) | ||
| if: always() | ||
| run: | | ||
| code=${{ steps.audit.outcome == 'success' && 0 || 1 }} | ||
| if [ "$code" -eq 0 ]; then exit 0; fi | ||
| echo "euthyna audit did not measure clean (or found security-classified history); see the step above." >&2 | ||
| exit 1 |
There was a problem hiding this comment.
issue (bug_risk): The optional two-step workflow cannot distinguish exit code 10 from exit codes 1 and 2: every non-successful audit outcome is converted to 1, so the enforcement step fails for flagged audits as well as measurement or usage errors. This contradicts the stated purpose of allowing 10 not to block merges.
Triggers: When a repository copies the two-step variant intending security-classified findings (10) to remain mergeable.
Suggested fix: Capture the audit process exit code explicitly, for example by writing $? to GITHUB_OUTPUT before enabling continue-on-error, then allow only code 10 and fail for 1 or 2.
| run: | | ||
| npx --yes euthyna@latest audit --base "origin/${{ github.base_ref }}" --head HEAD \ | ||
| | tee audit-report.txt | ||
| continue-on-error: true | ||
| id: audit | ||
| - uses: actions/upload-artifact@v4 | ||
| if: always() | ||
| with: | ||
| name: euthyna-audit-report | ||
| path: audit-report.txt |
There was a problem hiding this comment.
issue (broader_impact): The artifact-upload recipe pipes euthyna audit into tee without enabling pipefail, so the shell reports tee's successful status instead of the audit's exit code. A usage error, unmeasured result, or flagged result therefore makes this copied workflow step succeed and can silently turn the purported PR gate green.
Triggers: When this artifact snippet is used as the audit step in a gating workflow.
Suggested fix: Enable set -o pipefail before the pipeline, or capture the audit status explicitly while still writing the report file.
Closes the one gap the ChatGPT review surfaced: the exit-code contract (0/10/1/2) exists and is tested, but nothing shows how to wire it as a PR gate.
docs/ci-integration.md+-zh: copy-pasteaudit.yml(one step,npx euthyna@latest audit --base origin/<target>), the exit-code-to-merge-decision table, an optional two-step variant for when10should not block, artifact upload, and explicit does/does-not-answer boundaries (the workflow deliberately does not rungate).No CLI changes.
npm test207 pass / 0 fail on this tree before commit.Summary by Sourcery
Document how to integrate the existing
euthyna auditexit-code contract into GitHub Actions pull-request gates.New Features:
euthyna auditas a pull-request gate, including exit-code guidance, optional handling for non-blocking findings, and report artifacts.Enhancements:
euthyna gate.Documentation: