Skip to content

Commit a8e1fd3

Browse files
author
bootc-dev Bot
committed
Sync common files from infra repository
Synchronized from bootc-dev/infra@61b769a. Signed-off-by: bootc-dev Bot <bot@bootc.dev>
1 parent 90070ce commit a8e1fd3

8 files changed

Lines changed: 294 additions & 27 deletions

File tree

.bootc-dev-infra-commit.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
b23aa64010d014befa5adc5bc54363b6fb60a3e4
1+
61b769aee4ec165dcbfd993aeaa10a7fae2cb629

.devcontainer/devcontainer.json

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,17 @@
1313
},
1414
"features": {},
1515
"runArgs": [
16-
// Because we want to be able to run podman and also use e.g. /dev/kvm
17-
// among other things
18-
"--privileged"
16+
// In general we hope that the outer environment has set up
17+
// a user namespace to keep this secure.
18+
"--cap-add=all",
19+
// Required for mounting /proc in nested user namespace
20+
"--security-opt", "label=disable",
21+
// Allows access to /proc paths needed for nested containers
22+
"--security-opt", "unmask=/proc/*",
23+
// Device access for nested containers and VMs
24+
"--device", "/dev/net/tun",
25+
// I always want KVM
26+
"--device", "/dev/kvm"
1927
],
2028
"postCreateCommand": {
2129
// Our init script

.github/actions/bootc-ubuntu-setup/action.yml

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,7 @@ runs:
4747
IDV=$(. /usr/lib/os-release && echo ${ID}-${VERSION_ID})
4848
test "${IDV}" = "ubuntu-24.04"
4949
# plucky is the next release
50-
# Ubuntu uses different mirrors for different architectures:
51-
# - amd64: azure.archive.ubuntu.com/ubuntu (on Azure runners)
52-
# - arm64: ports.ubuntu.com/ubuntu-ports
53-
case "$(arch)" in
54-
x86_64)
55-
mirror="http://azure.archive.ubuntu.com/ubuntu"
56-
;;
57-
aarch64)
58-
mirror="http://ports.ubuntu.com/ubuntu-ports"
59-
;;
60-
*)
61-
echo "Unsupported architecture: $(arch)" >&2
62-
exit 1
63-
;;
64-
esac
65-
echo "deb ${mirror} plucky universe main" | sudo tee /etc/apt/sources.list.d/plucky.list
50+
echo 'deb http://azure.archive.ubuntu.com/ubuntu plucky universe main' | sudo tee /etc/apt/sources.list.d/plucky.list
6651
/bin/time -f '%E %C' sudo apt update
6752
# skopeo is currently older in plucky for some reason hence --allow-downgrades
6853
/bin/time -f '%E %C' sudo apt install -y --allow-downgrades crun/plucky podman/plucky skopeo/plucky just
@@ -73,13 +58,8 @@ runs:
7358
set -xeuo pipefail
7459
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
7560
sudo udevadm control --reload-rules
76-
# Only trigger if /dev/kvm exists (may not be available on arm64 runners)
77-
if [ -e /dev/kvm ]; then
78-
sudo udevadm trigger --name-match=kvm
79-
ls -l /dev/kvm
80-
else
81-
echo "Note: /dev/kvm not available on this runner"
82-
fi
61+
sudo udevadm trigger --name-match=kvm
62+
ls -l /dev/kvm
8363
# Used by a few workflows, but generally useful
8464
- name: Set architecture variable
8565
id: set_arch
@@ -91,6 +71,7 @@ runs:
9171
shell: bash
9272
run: |
9373
set -xeuo pipefail
74+
# renovate: datasource=github-releases depName=bootc-dev/bcvk
9475
export BCVK_VERSION=0.10.0
9576
# see https://github.com/bootc-dev/bcvk/issues/176
9677
/bin/time -f '%E %C' sudo apt install -y libkrb5-dev pkg-config libvirt-dev genisoimage qemu-utils qemu-kvm virtiofsd libvirt-daemon-system python3-virt-firmware
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: 'Setup Rust'
2+
description: 'Install Rust toolchain with caching and nextest'
3+
runs:
4+
using: 'composite'
5+
steps:
6+
- name: Install Rust toolchain
7+
uses: dtolnay/rust-toolchain@stable
8+
- name: Install nextest
9+
uses: taiki-e/install-action@v2
10+
with:
11+
tool: nextest
12+
- name: Setup Rust cache
13+
uses: Swatinem/rust-cache@v2
14+
with:
15+
cache-all-crates: true
16+
# Only generate caches on push to git main
17+
save-if: ${{ github.ref == 'refs/heads/main' }}
18+
# Suppress actually using the cache for builds running from
19+
# git main so that we avoid incremental compilation bugs
20+
lookup-only: ${{ github.ref == 'refs/heads/main' }}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Gate PRs on OpenSSF Scorecard regressions.
2+
#
3+
# See also: https://github.com/ossf/scorecard/issues/1270
4+
name: OpenSSF Scorecard
5+
6+
on:
7+
pull_request:
8+
branches:
9+
- main
10+
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
scorecard:
16+
name: Scorecard
17+
runs-on: ubuntu-24.04
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v6
21+
with:
22+
fetch-depth: 0
23+
24+
- name: Check for regressions
25+
uses: bootc-dev/actions/openssf-scorecard@main
26+
with:
27+
base-sha: ${{ github.event.pull_request.base.sha }}
28+
head-sha: ${{ github.event.pull_request.head.sha }}

.github/workflows/rebase.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Automatic Rebase
2+
on:
3+
pull_request:
4+
types: [labeled]
5+
6+
permissions:
7+
contents: read
8+
9+
jobs:
10+
rebase:
11+
name: Rebase
12+
if: github.event.label.name == 'needs-rebase'
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Generate Actions Token
16+
id: token
17+
uses: actions/create-github-app-token@v2
18+
with:
19+
app-id: ${{ secrets.APP_ID }}
20+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
21+
owner: ${{ github.repository_owner }}
22+
23+
- name: Checkout
24+
uses: actions/checkout@v6
25+
with:
26+
token: ${{ steps.token.outputs.token }}
27+
fetch-depth: 0
28+
29+
- name: Automatic Rebase
30+
uses: peter-evans/rebase@v4
31+
with:
32+
token: ${{ steps.token.outputs.token }}
33+
34+
- name: Remove needs-rebase label
35+
if: always()
36+
uses: actions/github-script@v8
37+
with:
38+
github-token: ${{ steps.token.outputs.token }}
39+
script: |
40+
await github.rest.issues.removeLabel({
41+
owner: context.repo.owner,
42+
repo: context.repo.repo,
43+
issue_number: context.issue.number,
44+
name: 'needs-rebase'
45+
});

AGENTS.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,18 @@ When generating substantial amounts of code, you SHOULD
2222
include an `Assisted-by: TOOLNAME (MODELNAME)`. For example,
2323
`Assisted-by: Goose (Sonnet 4.5)`.
2424

25+
## Code guidelines
26+
27+
The [REVIEW.md](REVIEW.md) file describes expectations around
28+
testing, code quality, commit organization, etc. If you're
29+
creating a change, it is strongly encouraged after each
30+
commit and especially when you think a task is complete
31+
to spawn a subagent to perform a review using guidelines (alongside
32+
looking for any other issues).
33+
34+
If you are performing a review of other's code, the same
35+
principles apply.
36+
2537
## Follow other guidelines
2638

2739
Look at the project README.md and look for guidelines

REVIEW.md

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# Code Review Guidelines
2+
3+
These guidelines are derived from analysis of code reviews across the bootc-dev
4+
organization (October–December 2024). They represent the collective expectations
5+
and standards that have emerged from real review feedback.
6+
7+
## Testing
8+
9+
Tests are expected for all non-trivial changes - unit and integration by default.
10+
11+
If there's something that's difficult to write a test for at the current time,
12+
please do at least state if it was tested manually.
13+
14+
### Choosing the Right Test Type
15+
16+
Unit tests are appropriate for parsing logic, data transformations, and
17+
self-contained functions. Use integration tests for anything that involves
18+
running containers or VMs.
19+
20+
Default to table-driven tests instead of having a separate unit test per
21+
case. Especially LLMs like to generate the latter, but it can become
22+
too verbose. Context windows matter to both humans and LLMs reading the
23+
code later (this applies outside of unit tests too of course, but it's
24+
easy to generate a *lot* of code for unit tests unnecessarily).
25+
26+
### Separating Parsing from I/O
27+
28+
A recurring theme is structuring code for testability. Split parsers from data
29+
reading: have the parser accept a `&str`, then have a separate function that
30+
reads from disk and calls the parser. This makes unit testing straightforward
31+
without filesystem dependencies.
32+
33+
### Test Assertions
34+
35+
Make assertions strict and specific. Don't just verify that code "didn't crash"—
36+
check that outputs match expected values. When adding new commands or output
37+
formats, tests should verify the actual content, not just that something was
38+
produced.
39+
40+
## Code Quality
41+
42+
### Parsing Structured Data
43+
44+
Never parse structured data formats (JSON, YAML, XML) with text tools like `grep`
45+
or `sed`.
46+
47+
### Shell Scripts
48+
49+
Try to avoid having shell script longer than 50 lines. This commonly occurs
50+
in build system and tests. For the build system, usually there's higher
51+
level ways to structure things (Justfile e.g.) and several of our projects
52+
use the `cargo xtask` pattern to put arbitrary "glue" code in Rust using
53+
the `xshell` crate to keep it easy to run external commands.
54+
55+
### Constants and Magic Values
56+
57+
Extract magic numbers into named constants. Any literal number that isn't
58+
immediately obvious—buffer sizes, queue lengths, retry counts, timeouts—should
59+
be a constant with a descriptive name. The same applies to magic strings:
60+
deduplicate repeated paths, configuration keys, and other string literals.
61+
62+
When values aren't self-explanatory, add a comment explaining why that specific
63+
value was chosen.
64+
65+
### Don't ignore (swallow) errors
66+
67+
Avoid the `if let Ok(v) = ... { }` in Rust, or `foo 2>/dev/null || true`
68+
pattern in shell script by default. Most errors should be propagated by
69+
default. If not, it's usually appropriate to at least log error messages
70+
at a `tracing::debug!` or equivalent level.
71+
72+
Handle edge cases explicitly: missing data, malformed input, offline systems.
73+
Error messages should provide clear context for diagnosis.
74+
75+
### Code Organization
76+
77+
Separate concerns: I/O operations, parsing logic, and business logic belong in
78+
different functions. Structure code so core logic can be unit tested without
79+
external dependencies.
80+
81+
It can be OK to duplicate a bit of code in a slightly different form twice,
82+
but having it happen in 3 places asks for deduplication.
83+
84+
## Commits and Pull Requests
85+
86+
### Commit Organization
87+
88+
Break changes into logical, atomic commits. Reviewers appreciate being able to
89+
follow your reasoning: "Especially grateful for breaking it up into individual
90+
commits so I can more easily follow your train of thought."
91+
92+
Preparatory refactoring should be separate from behavioral changes. Each commit
93+
should tell a clear story and be reviewable independently. Commit messages should
94+
explain the "why" not just the "what," and use imperative mood ("Add feature"
95+
not "Added feature").
96+
97+
### PR Descriptions
98+
99+
PRs should link to the issues they address using `Closes:` or `Fixes:` with
100+
full URLs. One reviewer noted: "I edited this issue just now to have
101+
`Closes: <URL>` but let's try to be sure we're doing that kind of thing in
102+
general in the future."
103+
104+
Document known limitations and caveats explicitly. When approaches have tradeoffs
105+
or don't fully solve a problem, say so. For complex investigations, use collapsible
106+
`<details>` sections to include debugging notes without cluttering the main
107+
description.
108+
109+
Think about broader implications: "But we'll have this problem across all repos
110+
right?" Consider how your change affects the wider ecosystem.
111+
112+
### Keeping PRs Current
113+
114+
Keep PRs rebased on main. When CI failures are fixed in other PRs, rebase to
115+
pick up the fixes. Reference the fixing PR when noting that a rebase is needed.
116+
117+
### Before Merge
118+
119+
Self-review your diff before requesting review. Catch obvious issues yourself
120+
rather than burning reviewer cycles.
121+
122+
Do not add `Signed-off-by` lines automatically—these require explicit human
123+
action after review. If code was AI-assisted, include an `Assisted-by:` trailer
124+
indicating the tool and model used.
125+
126+
127+
## Architecture and Design
128+
129+
### Workarounds vs Proper Fixes
130+
131+
When implementing a workaround, document where the proper fix belongs and link
132+
to relevant upstream issues. Invest time investigating proper fixes before
133+
settling on workarounds.
134+
135+
### Cross-Project Considerations
136+
137+
Prefer pushing fixes upstream when the root cause is in a dependency. Reduce
138+
scope where possible; don't reimplement functionality that belongs elsewhere.
139+
140+
When multiple systems interact (like Renovate and custom sync tooling), be
141+
explicit about which system owns what and how they coordinate.
142+
143+
### Avoiding Regressions
144+
145+
Verify that new code paths handle all cases the old code handled. When rewriting
146+
functionality, ensure equivalent coverage exists.
147+
148+
### Review Requirements
149+
150+
When multiple contributors co-author a PR, bring in an independent reviewer.
151+
152+
## Rust-Specific Guidance
153+
154+
Prefer rustix over `libc`. All `unsafe` code must be very carefully
155+
justified.
156+
157+
### Dependencies
158+
159+
New dependencies should be justified. Glance at existing reverse dependencies
160+
on crates.io to see if a crate is widely used. Consider alternatives: "I'm
161+
curious if you did any comparative analysis at all with alternatives?"
162+
163+
Prefer well-maintained crates with active communities. Consider `cargo deny`
164+
policies when adding dependencies.
165+
166+
### API Design
167+
168+
When adding new commands or options, think about machine-readable output early.
169+
JSON is generally preferred for that.
170+
171+
Keep helper functions in appropriate modules. Move command output formatting
172+
close to the CLI layer, keeping core logic functions focused on their primary
173+
purpose.

0 commit comments

Comments
 (0)