Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2cd390e62e |
@@ -0,0 +1,65 @@
|
||||
# .dockerignore does NOT use .gitignore semantics. Docker matches with
|
||||
# moby/patternmatcher: filepath.Match plus `**`, so `*` does not cross
|
||||
# `/` and an unprefixed pattern is anchored at the context root. Every
|
||||
# depth-independent pattern therefore needs `**/`, or `config/.env` and
|
||||
# `certs/server.key` still ship while this file reads as solved. Only
|
||||
# genuinely root-anchored entries go unprefixed. Never transplant these
|
||||
# into .gitignore, where `**/` is wrong.
|
||||
#
|
||||
# Matching is case-sensitive, so secrets use character ranges rather
|
||||
# than an ALL-CAPS twin, which would still miss `Server.Key`.
|
||||
#
|
||||
# Extend with this repo's own host-built artifacts, written anchored:
|
||||
# `/myapp`, never `**/myapp`, which also matches `cmd/myapp/` and
|
||||
# deletes the package directory from the context.
|
||||
|
||||
# .git is sent without its config. Without a VERSION build argument the
|
||||
# stage that compiles runs `git describe --tags --always` on .git, which
|
||||
# does not need .git/config; that file can hold a credential, such as a
|
||||
# password in a remote URL or the token the CI checkout step stores there.
|
||||
.git/config
|
||||
|
||||
# Agent scratch: one full checkout of the repo per in-flight agent.
|
||||
# Anchored because it occurs once where agents run at the repo root.
|
||||
# KNOWN GAP: a repo running agents in subdirectories still ships
|
||||
# `services/api/.claude/` and must add its own anchored entry.
|
||||
.claude
|
||||
|
||||
# Environment files. `*.env` covers bare `.env` and the `prod.env`
|
||||
# convention. Re-include a committed template with a negation if the
|
||||
# build needs one: `!docs/example.env`.
|
||||
**/*.[eE][nN][vV]
|
||||
**/.[eE][nN][vV].*
|
||||
**/.[eE][nN][vV][rR][cC]
|
||||
|
||||
# Private keys and the bundles carrying them. Public certificates
|
||||
# (*.crt, *.cer) are deliberately absent: they are legitimate inputs.
|
||||
**/*.[pP][eE][mM]
|
||||
**/*.[kK][eE][yY]
|
||||
**/*.[pP]12
|
||||
**/*.[pP][fF][xX]
|
||||
**/[iI][dD]_[rR][sS][aA]
|
||||
**/[iI][dD]_[dD][sS][aA]
|
||||
**/[iI][dD]_[eE][cC][dD][sS][aA]
|
||||
**/[iI][dD]_[eE][dD]25519
|
||||
|
||||
# Dependencies: restored inside the image, never copied in.
|
||||
**/node_modules
|
||||
|
||||
# OS metadata.
|
||||
**/.DS_Store
|
||||
**/Thumbs.db
|
||||
|
||||
# Editor state: never a build input, and it churns COPY.
|
||||
**/*.swp
|
||||
**/*.swo
|
||||
**/*~
|
||||
**/*.bak
|
||||
**/.idea
|
||||
**/.vscode
|
||||
**/*.sublime-*
|
||||
|
||||
# This repo's host-built artifacts: `make` and `make test-coverage`.
|
||||
/bsdaily
|
||||
/coverage.out
|
||||
/coverage.html
|
||||
+19
-6
@@ -24,10 +24,9 @@ FROM golang:1.26.4-alpine@sha256:3ad57304ad93bbec8548a0437ad9e06a455660655d9af01
|
||||
# Depend on lint stage passing
|
||||
COPY --from=lint /src/go.sum /dev/null
|
||||
|
||||
ARG VERSION=dev
|
||||
|
||||
# Install build deps plus the sqlite3 and zstd CLIs the tests/tool shell out to
|
||||
RUN apk add --no-cache make build-base sqlite zstd
|
||||
# Install build deps plus the sqlite3 and zstd CLIs the tests/tool shell out
|
||||
# to, and git, which the build step below derives the version with
|
||||
RUN apk add --no-cache make build-base sqlite zstd git
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
@@ -41,8 +40,22 @@ COPY . .
|
||||
# Run tests
|
||||
RUN make test
|
||||
|
||||
# Build (pure Go, no CGO required since we use modernc.org/sqlite)
|
||||
RUN CGO_ENABLED=0 go build -o /bsdaily ./cmd/bsdaily
|
||||
# Build (pure Go, no CGO required since we use modernc.org/sqlite).
|
||||
# The version stamped into the binary: the VERSION build argument when one is
|
||||
# given, otherwise `git describe --tags --always` of the .git the build context
|
||||
# carries: the tag on a tagged commit, tag-N-gHASH on a commit after one, the
|
||||
# short commit when no tag is reachable. A context that carries .git and still
|
||||
# yields no version fails the build. With neither, as from a source tarball,
|
||||
# the binary reports dev.
|
||||
ARG VERSION
|
||||
RUN version="${VERSION:-$(git describe --tags --always)}"; \
|
||||
if [ -e .git ] && { [ -z "$version" ] || [ "$version" = dev ] || \
|
||||
[ "$version" = unknown ]; }; then \
|
||||
echo "no version could be derived although the build context carries .git" >&2; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
CGO_ENABLED=0 go build -ldflags="-X main.Version=${version:-dev}" \
|
||||
-o /bsdaily ./cmd/bsdaily
|
||||
|
||||
# Runtime stage
|
||||
# alpine:3.21
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
.PHONY: all bootstrap setup check test lint fmt fmt-check build clean deps test-coverage test-integration install release release-snapshot docker hooks
|
||||
|
||||
# Version number
|
||||
VERSION := 0.1.0-dev
|
||||
# Stamped into the binary: the same `git describe` the Dockerfile runs, so a
|
||||
# host build reports the same version as the image; dev when it yields nothing.
|
||||
VERSION ?= $(shell git describe --tags --always)
|
||||
|
||||
# Default target
|
||||
all: bsdaily
|
||||
@@ -36,7 +37,7 @@ lint:
|
||||
|
||||
# Build binary (pure Go; no CGO required since we use modernc.org/sqlite).
|
||||
bsdaily: internal/*/*.go cmd/bsdaily/*.go
|
||||
CGO_ENABLED=0 go build -o $@ ./cmd/bsdaily
|
||||
CGO_ENABLED=0 go build -ldflags "-X main.Version=$(or $(VERSION),dev)" -o $@ ./cmd/bsdaily
|
||||
|
||||
# Clean build artifacts.
|
||||
clean:
|
||||
|
||||
@@ -15,11 +15,15 @@ pre-1.0
|
||||
# Next Step
|
||||
|
||||
Bring the repo into policy compliance in one commit: add .gitignore,
|
||||
.dockerignore, .editorconfig, and .golangci.yml. Verify `make check` stays
|
||||
green with the new lint config.
|
||||
.editorconfig, and .golangci.yml. Verify `make check` stays green with the new
|
||||
lint config.
|
||||
|
||||
# Completed Steps
|
||||
|
||||
- 2026-10-02: A plain `docker build .` and a host `make` build stamp the git tag
|
||||
or short commit into the binary, which `bsdaily` logs on the first line of
|
||||
every run and prints with `--version`; added the canonical `.dockerignore`,
|
||||
which keeps `.git/config` out of the build context.
|
||||
- 2026-07-07 Adopted scripts-to-rule-them-all: `script/` entrypoints,
|
||||
Makefile shims, README Entrypoints section
|
||||
- 2026-06-28: Fixed errcheck lint failures; added compilation smoke test;
|
||||
@@ -36,8 +40,7 @@ green with the new lint config.
|
||||
|
||||
# Future Steps
|
||||
|
||||
- Add .gitignore, .dockerignore, .editorconfig, .golangci.yml (the Next
|
||||
Step).
|
||||
- Add .gitignore, .editorconfig, .golangci.yml (the Next Step).
|
||||
- Expand tests beyond the compilation smoke test: unit tests for the
|
||||
extraction, verification, and atomic-publish paths.
|
||||
- Cut a first SemVer release once compliance and test coverage land.
|
||||
|
||||
@@ -10,6 +10,11 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// Version is the git tag or short commit, set at link time with -X by the
|
||||
// Dockerfile and the Makefile, logged on the first line of every run and
|
||||
// printed by --version. Builds that do not set it report dev.
|
||||
var Version = "dev"
|
||||
|
||||
func main() {
|
||||
logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
|
||||
Level: slog.LevelInfo,
|
||||
@@ -23,8 +28,11 @@ func main() {
|
||||
rootCmd := &cobra.Command{
|
||||
Use: "bsdaily",
|
||||
Short: "Extract a single day's data from the latest daily snapshot",
|
||||
Version: Version,
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
slog.Info("starting", "version", Version)
|
||||
|
||||
hasDate := dateFlag != ""
|
||||
hasFrom := fromFlag != ""
|
||||
hasTo := toFlag != ""
|
||||
|
||||
+11
-2
@@ -1,7 +1,8 @@
|
||||
#!/bin/sh
|
||||
# script/docker: build the Docker image tagged with the project name.
|
||||
# Identical in all repos; the tag comes from script/projectname.
|
||||
# Generic: needs no adaptation.
|
||||
# --no-cache because the gate phases the final stage depends on are RUN
|
||||
# steps, and a cached one is a check that did not run.
|
||||
set -eu
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
||||
@@ -9,7 +10,15 @@ ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
docker build -t "$("$SCRIPT_DIR/projectname")" .
|
||||
# Own line: a failing command substitution inside an argument does
|
||||
# not trip `set -e`, so the inline form degrades silently to an
|
||||
# empty constant. The VERSION build argument takes precedence over
|
||||
# the version a build stage derives from the .git in the context.
|
||||
version="$(git describe --tags --always --dirty 2>/dev/null || true)"
|
||||
[ -n "$version" ] || version="unknown"
|
||||
docker build --no-cache \
|
||||
--build-arg VERSION="$version" \
|
||||
-t "$("$SCRIPT_DIR/projectname")" .
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
Reference in New Issue
Block a user