|
|
|
|
@@ -1,6 +1,6 @@
|
|
|
|
|
---
|
|
|
|
|
title: Repository Policies
|
|
|
|
|
last_modified: 2026-03-10
|
|
|
|
|
last_modified: 2026-03-18
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
This document covers repository structure, tooling, and workflow standards. Code
|
|
|
|
|
@@ -59,6 +59,73 @@ style conventions are in separate documents:
|
|
|
|
|
`make check`. For server repos, `make check` should run as an early build
|
|
|
|
|
stage before the final image is assembled.
|
|
|
|
|
|
|
|
|
|
- **Dockerfiles must use a separate lint stage for fail-fast feedback.** Go
|
|
|
|
|
repos use a multistage build where linting runs in an independent stage based
|
|
|
|
|
on the `golangci/golangci-lint` image (pinned by hash). This stage runs
|
|
|
|
|
`make fmt-check` and `make lint` before the full build begins. The build stage
|
|
|
|
|
then declares an explicit dependency on the lint stage via
|
|
|
|
|
`COPY --from=lint /src/go.sum /dev/null`, which forces BuildKit to complete
|
|
|
|
|
linting before proceeding to compilation and tests. This ensures lint failures
|
|
|
|
|
surface in seconds rather than minutes, without blocking on dependency
|
|
|
|
|
download or compilation in the build stage.
|
|
|
|
|
|
|
|
|
|
The standard pattern for a Go repo Dockerfile is:
|
|
|
|
|
|
|
|
|
|
```dockerfile
|
|
|
|
|
# Lint stage — fast feedback on formatting and lint issues
|
|
|
|
|
# golangci/golangci-lint:v2.x.x, YYYY-MM-DD
|
|
|
|
|
FROM golangci/golangci-lint@sha256:... AS lint
|
|
|
|
|
WORKDIR /src
|
|
|
|
|
COPY go.mod go.sum ./
|
|
|
|
|
RUN go mod download
|
|
|
|
|
COPY . .
|
|
|
|
|
RUN make fmt-check
|
|
|
|
|
RUN make lint
|
|
|
|
|
|
|
|
|
|
# Build stage
|
|
|
|
|
# golang:1.x-alpine, YYYY-MM-DD
|
|
|
|
|
FROM golang@sha256:... AS builder
|
|
|
|
|
WORKDIR /src
|
|
|
|
|
|
|
|
|
|
# Force BuildKit to run the lint stage before proceeding
|
|
|
|
|
COPY --from=lint /src/go.sum /dev/null
|
|
|
|
|
|
|
|
|
|
COPY go.mod go.sum ./
|
|
|
|
|
RUN go mod download
|
|
|
|
|
COPY . .
|
|
|
|
|
RUN make test
|
|
|
|
|
|
|
|
|
|
ARG VERSION=dev
|
|
|
|
|
RUN CGO_ENABLED=0 go build -trimpath \
|
|
|
|
|
-ldflags="-s -w -X main.Version=${VERSION}" \
|
|
|
|
|
-o /app ./cmd/app/
|
|
|
|
|
|
|
|
|
|
# Runtime stage
|
|
|
|
|
FROM alpine@sha256:...
|
|
|
|
|
COPY --from=builder /app /usr/local/bin/app
|
|
|
|
|
ENTRYPOINT ["app"]
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Key points:
|
|
|
|
|
- The lint stage uses the `golangci/golangci-lint` image directly (it
|
|
|
|
|
includes both Go and the linter), so there is no need to install the
|
|
|
|
|
linter separately.
|
|
|
|
|
- `COPY --from=lint /src/go.sum /dev/null` is a no-op file copy that creates
|
|
|
|
|
a stage dependency. BuildKit runs stages in parallel by default; without
|
|
|
|
|
this line, the build stage would not wait for lint to finish and a lint
|
|
|
|
|
failure might not fail the overall build.
|
|
|
|
|
- If the project uses `//go:embed` directives that reference build artifacts
|
|
|
|
|
(e.g. a web frontend compiled in a separate stage), the lint stage must
|
|
|
|
|
create placeholder files so the embed directives resolve. Example:
|
|
|
|
|
`RUN mkdir -p web/dist && touch web/dist/index.html web/dist/style.css`.
|
|
|
|
|
The lint stage should not depend on the actual build output — it exists to
|
|
|
|
|
fail fast.
|
|
|
|
|
- If the project requires CGO or system libraries for linting (e.g.
|
|
|
|
|
`vips-dev`), install them in the lint stage with `apk add`.
|
|
|
|
|
- The build stage runs `make test` after compilation setup. Tests run in the
|
|
|
|
|
build stage, not the lint stage, because they may require compiled
|
|
|
|
|
artifacts or heavier dependencies.
|
|
|
|
|
|
|
|
|
|
- Every repo should have a Gitea Actions workflow (`.gitea/workflows/`) that
|
|
|
|
|
runs `docker build .` on push. Since the Dockerfile already runs `make check`,
|
|
|
|
|
a successful build implies all checks pass.
|
|
|
|
|
@@ -82,6 +149,42 @@ style conventions are in separate documents:
|
|
|
|
|
- `make test` must complete in under 20 seconds. Add a 30-second timeout in the
|
|
|
|
|
Makefile.
|
|
|
|
|
|
|
|
|
|
- **`make test` should use the conditional verbose rerun pattern.** Run tests
|
|
|
|
|
without `-v` (verbose) first. If tests fail, automatically rerun with `-v` to
|
|
|
|
|
show full output. This keeps CI logs and `docker build` output clean on
|
|
|
|
|
success (just package/suite summaries) while providing full diagnostic detail
|
|
|
|
|
on failure (every test case, every assertion). The general shell pattern:
|
|
|
|
|
|
|
|
|
|
```makefile
|
|
|
|
|
test:
|
|
|
|
|
@<test-command> || \
|
|
|
|
|
{ echo "--- Rerunning with -v for details ---"; \
|
|
|
|
|
<test-command-with-v>; exit 1; }
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Go example:
|
|
|
|
|
|
|
|
|
|
```makefile
|
|
|
|
|
test:
|
|
|
|
|
@go test -timeout 30s -race -cover ./... || \
|
|
|
|
|
{ echo "--- Rerunning with -v for details ---"; \
|
|
|
|
|
go test -timeout 30s -race -v ./...; exit 1; }
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Python example:
|
|
|
|
|
|
|
|
|
|
```makefile
|
|
|
|
|
test:
|
|
|
|
|
@python -m pytest || \
|
|
|
|
|
{ echo "--- Rerunning with -v for details ---"; \
|
|
|
|
|
python -m pytest -v; exit 1; }
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The `exit 1` ensures the target always fails after a rerun — the first run
|
|
|
|
|
already proved the tests are broken, so the build must not pass even if a
|
|
|
|
|
flaky test happens to succeed on the second attempt. The rerun exists solely
|
|
|
|
|
for diagnostic output.
|
|
|
|
|
|
|
|
|
|
- Docker builds must complete in under 5 minutes.
|
|
|
|
|
|
|
|
|
|
- `make check` must not modify any files in the repo. Tests may use temporary
|
|
|
|
|
|