-
Notifications
You must be signed in to change notification settings - Fork 0
ci: attach the packages to the release and gate the dependency tree #4
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
9 commits
Select commit
Hold shift + click to select a range
2009362
ci: attach the packages to the release and gate the dependency tree
marcinpsk 4cf483b
fix: write a Debian changelog trailer dpkg accepts
marcinpsk e052ad6
ci: run the checks on pull requests only
marcinpsk ef6c4a7
fix: refuse an incomplete package set before the release exists
marcinpsk 88f4f75
ci: gate the invariants clippy cannot express
marcinpsk 00df513
test: apply the duplicate-run policy to .yaml workflows too
marcinpsk f513c62
fix: close three gaps in the guards added by this branch
marcinpsk 0988e38
fix: close three more gaps in this branch's own guards
marcinpsk e5674a5
fix: deny rustc warnings in the manifest, and reject a bare push trigger
marcinpsk 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
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
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
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
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,39 @@ | ||
| # opengrep ruleset | ||
|
|
||
| Custom [opengrep](https://github.com/opengrep/opengrep) rules that encode this project's | ||
| `CLAUDE.md` correctness invariants as machine-checked gates, so the same classes of bug | ||
| stop coming back review after review. | ||
|
|
||
| ## Why opengrep, and not just clippy or CodeQL | ||
|
|
||
| - **clippy** is type aware and covers idiomatic Rust far better than a syntactic matcher, | ||
| but it cannot express "this method is only allowed inside this function". | ||
| - **CodeQL** (`CodeQL/Analyze (rust)`) covers broad dataflow SAST. | ||
| - **opengrep** fills the gap: cheap, readable patterns for *our* invariants, and it is the | ||
| same engine CodeRabbit runs. | ||
|
|
||
| ## Relationship to CodeRabbit | ||
|
|
||
| CodeRabbit auto-detects an opengrep config only when it is named `opengrep.yml` or | ||
| `semgrep.yml` (and a few variants), and when it finds one it runs *that* **instead of** its | ||
| default packs. This ruleset deliberately avoids those names, so CodeRabbit keeps running | ||
| its own packs while these rules are enforced separately by `scripts/opengrep-scan.sh` and | ||
| the CI job. Both rulesets apply. | ||
|
|
||
| ## Layout | ||
|
|
||
| | Path | Purpose | | ||
| | --- | --- | | ||
| | `.opengrep/agentx-ifstack-rules.yaml` | The ruleset, and the single source of truth. Named so CodeRabbit does not adopt it. | | ||
| | `.opengrep/tests/*.rs` | Rule-test fixtures. `// ruleid:` must match, `// ok:` must not. They violate the rules on purpose and are not part of the crate. | | ||
| | `scripts/opengrep-scan.sh` | Scan `src/`. Exits non-zero on any finding. | | ||
| | `scripts/opengrep-test.sh` | Run the rule-tests against the ruleset. | | ||
|
|
||
| ## Rules | ||
|
|
||
| | Rule | Invariant | | ||
| | --- | --- | | ||
| | `agentx-try-wait-outside-finish` | `try_wait` reaps the child and frees its pid, and that pid is the process group id, so reaping before the group kill lets `kill(-pgid)` reach an unrelated group. Reap only in `IpCommand::finish`. | | ||
| | `agentx-unwrap-outside-tests` | `unwrap` panics, and a panic aborts the daemon while systemd counts the restart. | | ||
|
|
||
| Suppress a deliberate exception on the line with `// nosemgrep: <rule-id>`. |
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,58 @@ | ||
| # Custom opengrep ruleset encoding this project's CLAUDE.md correctness invariants. | ||
| # These run ON TOP OF CodeRabbit's default opengrep packs: the file is intentionally | ||
| # NOT named opengrep.yml or semgrep.yml, because CodeRabbit treats such a file as its | ||
| # config and runs it INSTEAD OF its own packs. Here it is passed explicitly with | ||
| # --config by scripts/opengrep-scan.sh and the CI job, so both rulesets apply. | ||
| # | ||
| # Rule-test fixtures live in .opengrep/tests/; run them with scripts/opengrep-test.sh. | ||
| rules: | ||
| - id: agentx-try-wait-outside-finish | ||
| languages: [rust] | ||
| severity: ERROR | ||
| message: >- | ||
| try_wait reaps the child and frees its pid, and that pid is also the process | ||
| group id, so a later kill(-pgid) can reach an unrelated group. Reap only in | ||
| IpCommand::finish, which kills the group first. If a call is deliberately | ||
| outside that order, suppress it on the line with | ||
| `// nosemgrep: agentx-try-wait-outside-finish`. | ||
| metadata: | ||
| category: correctness | ||
| confidence: HIGH | ||
| references: | ||
| - "CLAUDE.md: kill the process group before the single reap" | ||
| paths: | ||
| exclude: | ||
| - "tests/**" | ||
| patterns: | ||
| - pattern: $CHILD.try_wait() | ||
| # Scope the exemption to IpCommand::finish. Matching the signature alone would | ||
| # exempt any same-shaped method added elsewhere. | ||
| - pattern-not: | ||
| patterns: | ||
| - pattern-inside: | | ||
| impl IpCommand { ... } | ||
| - pattern-inside: | | ||
| fn finish(&mut self) -> Result<ExitStatus> { ... } | ||
|
|
||
| - id: agentx-unwrap-outside-tests | ||
| languages: [rust] | ||
| severity: ERROR | ||
| message: >- | ||
| unwrap panics, and a panic aborts the daemon while systemd counts the restart. | ||
| Return an error, or use expect with a message when the invariant is local and | ||
| genuinely cannot fail. | ||
| metadata: | ||
| category: reliability | ||
| confidence: HIGH | ||
| references: | ||
| - "CLAUDE.md: validate at boundaries and fail fast, no silent panics" | ||
| paths: | ||
| exclude: | ||
| - "tests/**" | ||
| patterns: | ||
| - pattern: $VALUE.unwrap() | ||
| # The attribute makes a test module, not its name. `$_` matches any module name; | ||
| # a named metavariable does not match a Rust module declaration here. | ||
| - pattern-not-inside: | | ||
| #[cfg(test)] | ||
| mod $_ { ... } |
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,41 @@ | ||
| // Fixture for agentx-try-wait-outside-finish. Contains rule-violating code on purpose. | ||
|
|
||
| impl IpCommand { | ||
| fn finish(&mut self) -> Result<ExitStatus> { | ||
| let mut child = self.child.take().expect("unreaped ip child"); | ||
| kill_group(child.id()); | ||
| // ok: agentx-try-wait-outside-finish | ||
| match child.try_wait() { | ||
| Ok(Some(status)) => Ok(status), | ||
| _ => Err(Error::other("not reaped")), | ||
| } | ||
| } | ||
|
|
||
| fn reap_early(&mut self) -> Result<()> { | ||
| let child = self.child.as_mut().expect("unreaped ip child"); | ||
| // ruleid: agentx-try-wait-outside-finish | ||
| let _ = child.try_wait()?; | ||
| Ok(()) | ||
| } | ||
| } | ||
|
|
||
| fn wait_bounded(child: &mut Child) -> Result<ExitStatus> { | ||
| loop { | ||
| // ruleid: agentx-try-wait-outside-finish | ||
| if let Some(status) = child.try_wait()? { | ||
| return Ok(status); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // A method with the same signature in another type must not inherit the exemption. | ||
| impl SomethingElse { | ||
| fn finish(&mut self) -> Result<ExitStatus> { | ||
| let mut child = self.child.take().expect("unreaped child"); | ||
| // ruleid: agentx-try-wait-outside-finish | ||
| match child.try_wait() { | ||
| Ok(Some(status)) => Ok(status), | ||
| _ => Err(Error::other("not reaped")), | ||
| } | ||
| } | ||
| } |
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,41 @@ | ||
| // Fixture for agentx-unwrap-outside-tests. Contains rule-violating code on purpose. | ||
|
|
||
| fn production(input: &str) -> u32 { | ||
| // ruleid: agentx-unwrap-outside-tests | ||
| input.parse::<u32>().unwrap() | ||
| } | ||
|
|
||
| fn production_ok(input: &str) -> Result<u32> { | ||
| // ok: agentx-unwrap-outside-tests | ||
| input.parse::<u32>().map_err(Error::other) | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
|
|
||
| #[test] | ||
| fn parses() { | ||
| // ok: agentx-unwrap-outside-tests | ||
| assert_eq!(production_ok("7").unwrap(), 7); | ||
| } | ||
| } | ||
|
|
||
| // A module literally named tests, but without #[cfg(test)], is production code. | ||
| mod outer { | ||
| mod tests { | ||
| fn helper(input: &str) -> u32 { | ||
| // ruleid: agentx-unwrap-outside-tests | ||
| input.parse::<u32>().unwrap() | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // A test module may carry any name; the attribute is what makes it a test module. | ||
| #[cfg(test)] | ||
| mod unit_tests { | ||
| fn helper() { | ||
| // ok: agentx-unwrap-outside-tests | ||
| let _ = "7".parse::<u32>().unwrap(); | ||
| } | ||
| } |
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
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
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,31 @@ | ||
| # Supply-chain gate for the dependency tree. Dependabot raises version bumps, but it | ||
| # does not report whether the tree as locked carries a known advisory. | ||
|
|
||
| [graph] | ||
| # The release binary is built for musl, so resolve the tree that actually ships. | ||
| targets = [{ triple = "x86_64-unknown-linux-musl" }] | ||
|
|
||
| [advisories] | ||
| version = 2 | ||
| # RUSTSEC advisories fail the build. Add an id here only with a comment saying why. | ||
| ignore = [] | ||
|
|
||
| [licenses] | ||
| version = 2 | ||
| # The package ships as a .deb and .rpm with a copyright file, so a copyleft crate | ||
| # arriving through a transitive dependency is a packaging problem, not only a legal one. | ||
| allow = [ | ||
| "MIT", | ||
|
|
||
| "Apache-2.0", | ||
| "Unlicense", | ||
| "Unicode-3.0", | ||
| ] | ||
|
|
||
| [bans] | ||
| multiple-versions = "warn" | ||
| wildcards = "deny" | ||
|
|
||
| [sources] | ||
| unknown-registry = "deny" | ||
| unknown-git = "deny" |
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 |
|---|---|---|
|
|
@@ -2,7 +2,7 @@ agentx-ifstack (0.0.2-1) unstable; urgency=medium | |
|
|
||
| * Release 0.0.2. See CHANGELOG.md for the change list. | ||
|
|
||
| -- Marcin Zieba <[email protected]> Fri, 11 Sep 2026 18:05:06 GMT | ||
| -- Marcin Zieba <[email protected]> Fri, 11 Sep 2026 18:05:06 +0000 | ||
|
|
||
| agentx-ifstack (0.1.0-1) unstable; urgency=medium | ||
|
|
||
|
|
||
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
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
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.