126 Commits
Author SHA1 Message Date
Tosone ee12dbda37 docs(agents): document lint version, govulncheck and storage tests
Sync the golangci-lint version, note the new govulncheck workflow, drop
the removed codeql.yml reference, and record that the pkg/storage test
suites are run manually against cloud resources.
2026-10-03 16:20:36 +08:00
Tosone 9d0affcd12 build(ci): pin govulncheck and add a non-blocking scan workflow
Add golang.org/x/vuln/cmd/govulncheck to the go.mod tool set and run it
in a dedicated workflow with the project build tags. The report is
written to GITHUB_STEP_SUMMARY and the step is non-blocking so findings
are reported without failing CI.

Verification:
- go tool govulncheck -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./...
2026-10-03 16:20:36 +08:00
Tosone 1fefe15ea5 refactor(test): use t.Context in unit tests
Replace context.Background() with t.Context() so test contexts are
canceled when the test ends, which surfaces leaked background work. The
pkg/storage suites are intentionally left unchanged because they run
manually against cloud resources.

Verification:
- go vet ./...
2026-10-03 16:20:36 +08:00
Tosone 2cc50352ce refactor(clients): propagate request context through registry clients
Thread the caller context through ClientsFactory.New and
Clients.AuthToken so proxied blob and manifest requests keep
cancellation and trace propagation instead of starting from
context.Background(). Regenerate the mock and update callers and tests.
Document the intentionally background contexts in the one-shot builder
CLI.

Verification:
- go generate ./pkg/distribution/clients/... (no diff)
- go vet ./...
2026-10-03 16:20:36 +08:00
Tosone d2d9e94c12 build(lint): enable the modernize linter
Turn on golangci-lint's modernize linter so the go fix modernizations
are enforced going forward.

Verification:
- golangci-lint run (0 issues)
2026-10-03 16:20:36 +08:00
Tosone c6b0f93ff4 refactor: apply go fix modernizations
Adopt modern Go and stdlib idioms surfaced by the modernize analyzer:
promote embedded fields in struct literals, and replace hand-written
equivalents with maps.Copy, min, atomic.Int64, new(expr) and
slices.SortStableFunc.

Verification:
- go fix -diff ./... (no remaining changes)
- go vet ./...
2026-10-03 16:20:36 +08:00
Tosone e7df1342b5 refactor(web): modernize namespace page and use @ import alias
Reformat the page, switch relative imports to the @ alias, replace the
inline update/delete buttons with a dropdown row-actions menu, and use
exponentiation for the TiB/GiB/MiB size conversion.

Verification:
- cd web && bunx tsc --noEmit
- cd web && bun run lint
2026-10-03 00:33:57 +08:00
Tosone 95c6006fa1 fix(web): use exponentiation for size unit conversions
JavaScript bitwise shifts operate on 32-bit integers, so `1 << 40` evaluates
to `1 << 8` (256) instead of 1 TiB, corrupting TiB size limits and the
calcUnit TiB branch. Replace the shifts with exponentiation.

Verification:
- cd web && bunx tsc --noEmit
- cd web && bun run lint
2026-10-03 00:27:26 +08:00
Tosone 217cec5829 build(deps): bump go and web dependencies
- Update go.mod/go.sum (grype, syft, aws-sdk-go-v2, distribution,
  gin contrib, validator and others).
- Update web/package.json and web/bun.lock (shikijs, react-router-dom,
  lucide-react, oxlint, esbuild, vite and others).
- Ignore the local `.delta/` directory in .gitignore.
2026-10-02 23:36:56 +08:00
Tosone dbd9601947 refactor(web): unify namespace UI and modernize tables, tabs and dialogs
- Add a shared NamespaceTabs component and use underline tabs across the
  namespace summary, repository, member, daemon task and webhook pages.
- Redesign the pagination footer with theme tokens and a page indicator,
  and give previous/next proper pointer and disabled states.
- Align the daemon task and webhook table headers with the namespace list
  style, drop bold text, and use a muted header color.
- Convert the namespace member list to the shadcn Table component and
  match the search/create toolbar height.
- Modernize the webhook create dialog (Input, Label, Switch, two-column
  events) and unify button and input styles.
- Make the namespace summary markdown editor fill the available height.
- Stay silent on 404/empty responses for the namespace summary, member
  and webhook requests instead of showing an error toast.
- Add standard `appearance` declarations and update deprecated Tailwind
  classes to clear editor warnings.

Verification: bunx tsc --noEmit; bunx oxlint; bun run build (web)
2026-10-02 23:34:29 +08:00
Tosone eca764eda4 test(logger): split coverage tests by covered source file
Drop the coverage_test.go catch-all and distribute its cases to the test
files matching the units they exercise: logger_test.go for logger.go,
glog_test.go for glog.go, and a new trace_handler_test.go for the trace
handler.

Verification:
- go test -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./pkg/logger/
- golangci-lint run --build-tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./pkg/logger/...
2026-09-28 21:24:36 +08:00
Tosone 44440383a4 ci(testkit): exclude pkg/testkit from unit tests
The testkit package only provides test helpers, so skip it in the unit-test
package matrix and coverage run, matching the other infrastructure-only
excludes.
2026-09-28 21:24:33 +08:00
Tosone f6d7a97cdf fix(rs3): probe /readyz and drop unused RS3_ENDPOINT
The rs3 server binary never reads RS3_ENDPOINT; it is a client-only setting
for rs3-cli, which only the old healthcheck used. Switch the rs3 healthcheck
to `curl --fail .../readyz` with a start period (matching scripts/run_rs3.sh
and CI) and remove the now-dead RS3_ENDPOINT from compose.yml, the demo-server
compose, run_rs3.sh, and the test workflow.

Verification:
- git grep RS3_ENDPOINT -> no matches
- docker compose config for compose.yml and tools/demo-server/compose.yml
2026-09-28 20:55:25 +08:00
Tosone bb9b02adf4 test(storage): remove stray filesystem test artifacts
These files are created and deleted by the filesystem storage tests at
runtime and were committed by accident; drop them from the tree.
2026-09-28 20:55:25 +08:00
Tosone 7dd41773a5 docs(ptr): remove stale generated README
The gomarkdoc output referenced the upstream code.byted.org import path and
is not maintained for this package.
2026-09-28 20:55:25 +08:00
Tosone 47dc5db656 docs(todo): move non-HA backlog above completed list
Promote the password recovery flow to its own backlog section and renumber
the completed items so the remaining non-HA work is grouped together.
2026-09-28 20:55:25 +08:00
Tosone 747da40b7d test(utils): generate hash and compress fixtures at runtime
Delete the checked-in ci.txt and test.txt fixtures and write them into
t.TempDir() inside the hash and compress tests, keeping the fixture content
in package constants so the expected digests stay unchanged.

Verification:
- go test -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./pkg/utils/hash/ ./pkg/utils/compress/
2026-09-28 20:55:25 +08:00
Tosone ed3b2d2563 docs(hash): translate comments to English
Translate the remaining Chinese doc comments on FileVerify, String, and File
into English, and drop the unused package-only doc.go file.
2026-09-28 20:32:19 +08:00
Tosone 3327863518 refactor(infra): move mocks into per-package mocks subpackages
Move the cache, counter, lock, and workq mock files from their package
directories into a `mocks` subpackage, matching the existing service and
storage layout. Update the `//go:generate` directives to emit into
`mocks/*_mocks.go` with package `mocks`, regenerate the files, and document
the convention in AGENTS.md.

Verification:
- go test -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./pkg/infra/...
- go vet -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./pkg/infra/...
2026-09-28 20:32:17 +08:00
Tosone 44fd74b66d test(logger): raise package coverage to 100%
Add tests for SetLevel branches, source trimming, the log writer error path,
formatLogLine error branches, gorm trace logging, the Logger methods, both
Fatal helpers (via a re-exec subprocess) and the trace handler.

Split databaseTraceCall into a thin wrapper plus databaseTraceCallFrom(caller)
so the stack walk can be tested with a fake caller; the behavior is unchanged.
2026-09-27 14:57:02 +08:00
Tosone 9ec5d37b28 refactor(server): move request validators under server
pkg/validators is the gin request-validation layer: it registers gin's
binding.Validator and is used by the HTTP handlers, so move it to
pkg/server/validators where the rest of the HTTP layer lives.

The only non-server consumer was pkg/background/daemon, which called
validators.Initialize() even though the worker never uses gin binding
validation. Drop that call so the worker does not depend on the server
package; the server still initializes validators through
handlers.Initialize.
2026-09-27 14:57:02 +08:00
Tosone d516c5707c refactor(storage): move storage mock into a mocks subpackage
Move pkg/storage/storage_mocks.go to pkg/storage/mocks/ (package mocks) so the
generated mock is not counted in the storage package coverage, and update the
//go:generate directive and the tests that referenced the mock.
2026-09-27 12:37:00 +08:00
Tosone 9a7e6c8655 test(telemetry): cover context helpers and tracer initialization
Add tests for every context helper and for Init across disabled, http, grpc
and invalid protocol configurations, raising coverage from 21.6% to 98.6%.

This also surfaced a real bug: Init failed when tracing was enabled because
resource.Default() (schema 1.43.0) conflicted with semconv.SchemaURL
(1.26.0). Build the service name resource schemaless so Init succeeds.
2026-09-27 12:37:00 +08:00
Tosone fb7f20e8c4 refactor(service): move service mocks into per-domain mocks subpackages
Move every pkg/service/<domain>/*_mocks.go into pkg/service/<domain>/mocks/
(package mocks) so generated mocks are no longer part of the packages under
test and stop depressing their coverage. Update the //go:generate directives
and the tests that referenced the mocks.
2026-09-27 12:37:00 +08:00
Tosone fe9b072a11 chore: consolidate validators coverage, repository mocks and test database
Raise the validators package coverage from 49.2% to 97.1% with table-driven
tests for every validation function and fold the repetitive RegisterValidation
checks in newValidator into one loop.

Move the repository mocks out of the packages under test into per-domain mocks
subpackages, update the //go:generate directives and test imports, skip the
mocks packages in the CI test matrix and drop the unused Codecov config.

Default InitializeIntegration to the turso dialect so integration tests run
locally without a PostgreSQL server.
2026-09-27 12:37:00 +08:00
Tosone c70127b0d1 feat(config): initialize namespaces from configuration
Replace the hard-coded library namespace seed with an idempotent bootstrap
task driven by a new namespace.initialize config list, so users can declare
any number of namespaces and set the visibility of each one (public or
private). The task only creates namespaces that do not exist yet.

Remove the seed INSERT from the four 0001 migrations and wire the new config
into the example configs, the docs and the Helm chart (values + configmap).
2026-09-27 11:11:04 +08:00
Tosone 93cf7c1946 chore(dal): document UserRecoverCode and track its recovery gap
Add an explicit TableName() for UserRecoverCode and document that the
password recovery backend is wired up (endpoints, service, repository and
generated query) but the code is never delivered to users and the web UI has
no recover pages. Track the remaining work in TODO.md.
2026-09-27 11:10:47 +08:00
Tosone 68c4cb8be1 chore(dal): remove unused Locker model
pkg/dal/models/locker.go is dead code: it is absent from the gorm-gen model
list in pkg/dal/cmd/gen.go, has no generated query, and no migration creates
a lockers table. Locking is handled by pkg/infra/lock instead.
2026-09-27 11:10:43 +08:00
Tosone 2009156bf5 ci: replace Minio with rs3 and make E2E CI run
Run the self-hosted rs3 service instead of Minio in test.yml and swap the
local helper script, Makefile helm values, and AGENTS.md notes accordingly.

Fix the E2E workflow (refs #426): it only triggered on the `main` branch,
which does not exist in this repository, so the job never ran. Trigger it
on `dev` for both push and pull_request like test.yml, build the image via
the consolidated `make docker-build`, bump the checkout/setup-go actions,
drop the hosted-toolcache cleanup, and refresh the E2E tooling to k6
v2.3.0 and skopeo v1.24.1.

Repair the image startup path as well: start nginx with an explicit
/etc/nginx/nginx.conf and a /dev/stderr error log so the non-root user does
not touch the compiled-in log path, create /etc/sigma with mode 0755 before
copying config.yaml (COPY --chmod made the directory non-traversable), and
disable redis in the shipped default config since cache, locker and work
queue are inmemory.
2026-09-26 19:42:46 +08:00
Tosone f054f7bdd1 chore: add YAML language server schema hints and pin node in mise
Reference JSON schemas at the top of CI workflows and tool configs so
editors can validate and autocomplete them, and add node to mise.toml.
2026-09-26 12:36:33 +08:00
Tosone d1d15108c8 ci: switch coverage upload from Codecov to Coveralls
Replace the codecov/codecov-action step with coverallsapp/github-action,
using COVERALLS_REPO_TOKEN and the golang format for the Go coverprofiles
emitted by `go test -coverprofile`. Update the README badges and the CI
workflow notes so no references to Codecov remain.

Verification:
- Ruby YAML parse of .github/workflows/test.yml
2026-09-20 13:34:09 +08:00
Tosone 2ac08864f6 ci(lint): run oxlint for the web app
Add a `Lint web` step to the lint workflow so the frontend gets the same
treatment as the Go code. It reuses the dependencies installed by the
existing `Build web` step (same job, same bun cache) and runs
`bun run lint`, which is the oxlint invocation configured in
web/package.json and web/.oxlintrc.json — no extra setup or duplicated
dependency install required.

Verification: parsed the workflow YAML and confirmed the step order is
Checkout -> Setup golang -> Setup bun -> Cache bun -> Build web ->
Lint web -> Run golangci-lint -> Lint Dockerfile; `cd web && bun run lint`
exits 0 locally (0 warnings, 0 errors).
2026-09-17 16:16:25 +08:00
Tosone 3b99c1d305 chore(web): enable react/perf lint rules and resolve every finding
Turn on the react, react-hooks, suspicious and perf rule sets in oxlint and
fix the 2665 diagnostics they report instead of muting the rules:

- validation/limit state is derived during render instead of being synced
  in an effect (namespace/repository/tag limits, size limit + unit,
  username/email/password checks in Menu, Users, Webhook and Member)
- refetch triggers are gone: mutation handlers now call the memoized fetcher
  directly (Namespace list and members, Menu token timer) instead of bumping
  a `refresh` state that only existed to re-run an effect
- data fetchers (fetchNamespace/fetchTags/fetchRepository/fetchWebhook/
  fetchMembers/logout) are memoized with useCallback and their effects use
  correct dependency arrays; the async profile seeding uses an override state
  instead of an effect
- fix 39 shadowed variables (resp/err/*ListData/configData/requestUrl/...),
  use stable list keys instead of array indexes, hoist `cutDigest` to module
  scope and memoize the ToggleGroup context value
- replace the ported HTML5 email pattern with a zod based `isEmail` helper
  (zod 4, `z.email()`), dropping the control-character regex
- use-mobile seeds its state lazily and Shiki derives the highlighted html
  with useMemo

.oxlintrc.json pins the setup: plugins react/typescript/unicorn/oxc,
correctness as error, suspicious/perf as warn, `_`-prefixed names ignored by
no-unused-vars, and react-in-jsx-scope off because the app uses the React 19
automatic JSX runtime (that rule only applies to React < 17).

Verification: web: `bun run lint` (0 warnings, 0 errors, no
oxlint-disable directives left in src); `tsc --noEmit`; `vite build`;
unused-import scan reports 0.
2026-09-17 16:13:02 +08:00
Tosone 8bb35e880b chore(web): clear oxlint warnings and pin its configuration
Fix the diagnostics that oxlint reports on the codebase instead of
silencing the rules:

- unused event parameters (41): `onClick={e => ...}` -> `onClick={() => ...}`
  and `.catch(err => ...)` -> `.catch(() => ...)` where the argument was
  never used
- unused state members: keep only the half that is used
  (`const [sortOrder] = useState(...)`, `const [, setUserObj] = ...`), and
  drop the sort state in CodeRepository/List that was fully unused
- unused props/locals: drop `index` from TableItem/TableItemDropdown (plus
  interface and call sites), `namespace`/`repository` from Tag TableItem,
  two dead `const user = ...` in Login/Callback and the unused `u` URL in
  Webhook/List, along with the imports that became unused (IUserSelf, IOrder)
- one-line effects (10): `useEffect(() => { cond && setX() }, [dep])` ->
  explicit `if (cond) { setX(); }`
- utils/index.ts: keep the HTML5 email pattern as-is with a scoped
  `oxlint-disable-next-line no-control-regex` and a reason

Add .oxlintrc.json to pin the setup: correctness rules are errors,
no-unused-vars ignores `_`-prefixed names, browser/es2024 globals,
dist/node_modules/public ignored. The rule set matches the previous
defaults, so nothing is disabled to hide a warning.

Verification: web: `bun run lint` (0 warnings, 0 errors); `tsc --noEmit`;
`vite build`; unused-import scan reports 0.
2026-09-17 15:40:19 +08:00
Tosone 3ca56e7b67 refactor(web): replace @headlessui/react with shadcn components
Swap every headlessui usage for the shadcn/base-ui components that are
already bundled in the app, then drop the dependency:

- menus (8): Menu/MenuButton/MenuItems/MenuItem + Transition -> DropdownMenu;
  role checks that guarded the original clicks are preserved as
  DropdownMenuItem `disabled`
- dialogs (14): Dialog/DialogPanel/DialogTitle + Transition* -> Dialog,
  DialogContent, DialogTitle, DialogDescription, DialogFooter and Button
- listboxes (6): Listbox -> Select; the multiple-selection one becomes a
  DropdownMenu with DropdownMenuCheckboxItem
- comboboxes (9): Combobox -> Popover + Command, wiring the existing search
  state into CommandInput and keeping shouldFilter={false} for server-side
  search
- remove @headlessui/react from package.json/bun.lock

Also included:
- drop imports that became unused (Table/Button in Builder/RunnerList,
  Separator, useSidebar, dayjs, Link/useParams, Check/ChevronsUpDown and the
  leftover shadcn imports in the webhook pages)
- replace Tailwind v4 arbitrary sizes that have spacing-scale equivalents
  (w-[350px] -> w-87.5, h-[36px] -> h-9, after:top-[2px] -> after:top-0.5, ...);
  h-[18.4px] is intentionally kept since 4.6 is not a multiple of 0.25
- fix the webhook log delete-confirm label (was "Resend")
- add oxlint with `lint` and `lint:fix` scripts

Verification: web: `tsc --noEmit`; `vite build`; `oxlint` (0 errors,
72 pre-existing warnings); scripted scan reports 0 unused imports and no
remaining @headlessui imports.
2026-09-17 15:31:21 +08:00
Tosone 959b2f2ee6 feat(web): polish layout, sidebar, tables and utils
Follow up the shadcn/ui migration with a round of layout and UX fixes:

- layout: unify the horizontal padding of the page header, page toolbars,
  table headers/cells and pagination on `px-4`, so titles, search boxes and
  the first/last table columns share one left/right baseline while the table
  itself stays full width.
- sidebar: stop the SidebarProvider wrapper (`w-full`) from squeezing the
  page content, enlarge the menu rows, lighten the active background through
  a new `--sidebar-active` token, drop the bold active label, and always show
  a pointer cursor for buttons and menu items.
- user menu: fold API docs, theme and language into the bottom dropdown,
  persist username/email on login, callback and token refresh, fall back to
  "sigma" when no username is known, and expose a Login entry for guests.
- tables: replace the row action dropdown with inline update/delete icon
  buttons (delete in red), right align the Action column, only render sort
  arrows for the active sort, keep namespace/repository names readable on
  hover, and render created/updated columns as relative times.
- components: add `RelativeTime` (dayjs relativeTime + tooltip) and the
  `Field`/`FieldLabel` primitives, rebuild the login page on top of them,
  and bump the shared button/input/select/toggle/tabs presets to h-9.
- home: lay the summary cards out in a responsive grid instead of a fixed
  1600px wide row that overflowed the viewport.
- utils: merge the short helper modules into `utils/index.ts` (trimHTTP,
  calcUnit, Regex, Tooltip) and `utils/request.ts` (axios interceptors plus
  token refresh), leaving only index/request/distros.

Verification:
- `npx tsc --noEmit`
- `npx vite build`
2026-09-16 22:41:24 +08:00
Tosone b10d58b948 build(deps): bump go dependencies and build tool versions
- build/Dockerfile: swagger-ui 5.33.0, syft 1.51.1, grype 0.118.0
- go.mod: aws-sdk-go-v2 config/credentials/kms/sts, docker/cli 29.8.1,
  mark3labs/mcp-go 1.1.0, go.podman.io/* 6.1.2, gorm postgres driver 1.6.3
- add mise.toml pinning the Go and Bun toolchain versions

Verification: go mod verify; go build -tags
"netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./...
2026-09-16 20:04:43 +08:00
Tosone 2723ffb4b0 test(service): add unit tests for distribution, daemons, oauth2, and manifest services
Add mock-based unit tests to five service packages, raising statement
coverage on the business-logic layer:

- distribution/upload: 5.6% -> 54.0%
- distribution/blob: 9.8% -> 31.1%
- daemons: 0.6% -> 48.6%
- oauth2: 2.7% -> 22.8%
- distribution/manifest: 27.1% -> 34.1%

Tests cover error mapping (not-found vs internal), auth branches (Basic
password verify / Bearer token validate), namespace ownership checks, GC
rule/runner/record get-list across all four GC types, digest verification,
redirect handling, and artifact-type classification.

Transaction success paths (query.Q.Transaction) remain uncovered at the
unit level by design, matching the existing service-test convention; those
paths are exercised by handler/DB tests.

Verification:
- go test -count=1 -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./pkg/service/daemons/ ./pkg/service/oauth2/ ./pkg/service/distribution/manifest/ ./pkg/service/distribution/upload/ ./pkg/service/distribution/blob/
- go vet -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./pkg/service/daemons/ ./pkg/service/oauth2/ ./pkg/service/distribution/manifest/
2026-09-14 23:19:12 +08:00
Tosone 9cdeabcb2b test(handlers): add handler unit tests for four under-tested packages
Cover webhooks, builders, coderepos and daemons handler packages with
gomock-based tests that assert both the happy paths and the error and
authorization branches:

- webhooks: create/list/get/put/delete, ping, log list/get/delete/resend
- builders: builder CRUD plus runner list/get/run/rerun/stop/log guards
- coderepos: list/get/owners/branches/resync/providers/user3rdparty
- daemons: all 32 gc-* endpoints across blob/tag/repository/artifact

Package statement coverage after this change: webhooks 43.6%, builders
63.7%, coderepos 73.4%, daemons 86.9% (previously ~3-5%).

Verification:
CI_DATABASE_TYPE=turso go test -parallel 1 -failfast   -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp"   -timeout 30m ./pkg/server/handlers/webhooks/... ./pkg/server/handlers/builders/...   ./pkg/server/handlers/coderepos/... ./pkg/server/handlers/daemons/...
gofmt -w <new test files> && golangci-lint run --new
2026-09-14 20:36:36 +08:00
Tosone f677ad3f5f docs: complete placeholder doc comments across the codebase
Replace every `// <Identifier> ...` placeholder doc comment with a real
description of the declared symbol. 276 comments in 71 files were rewritten:
149 top-level placeholders first, then a follow-up scan caught another 127
indented ones (interface methods and const blocks) that a column-anchored
match had missed.

Comments now open with the declared identifier and record the actual
contract - behaviour, side effects, error/panic conditions, units, HTTP
endpoints, lock keys and cache prefixes - instead of restating the
signature. Three placeholders carried a stale identifier and were corrected
to the declared symbol: ConfigurationDatabasePostgresql, GetImageRef and
Initialize.

No functional change: every modified line is a comment.

Verification:
- grep '^\s*//\s+\S+\s+\.\.\.\s*$' over all *.go returns no matches
- gofmt -l over the changed files prints nothing
- CGO_ENABLED=1 go build -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./... exits 0
- git diff HEAD -U0 filtered to non-comment changed lines is empty
2026-09-14 14:58:06 +08:00
Tosone a7c816494a feat(auth): add login rate limit configuration
Add login failure rate limiting with per-username tracking, supporting both delay-based throttling and lockout via configurable backend.
Update all sample configs, Helm templates, and documentation to include the new auth loginRateLimit settings.

Verification:
All config files, Helm charts, and docs are updated to match the new configuration schema.
2026-09-13 15:26:25 +08:00
Tosone 2adc82c54b refactor(cache): rename package from cacher to cache
Rename the cache module package name from `cacher` to `cache` across all files, including:
- Update all internal package declarations
- Fix import aliases in dependent modules
- Correct mockgen package configuration
- Update cache interface and error type references

This aligns the package naming with the module directory structure and improves consistency across the codebase.
2026-09-13 14:48:06 +08:00
Tosone ac246ad163 feat(authn): throttle failed logins per username
Add a cache-backed failed-login throttler for Basic auth. Once a username
reaches auth.loginRateLimit.maxFailures failures within window, each
subsequent authentication attempt is delayed by delay (capped at 5s)
instead of being rejected; the counter is cleared on a successful login.

- add pkg/infra/ratelimit backed by pkg/infra/cache (inmemory/redis) with
  Count/Incr/Reset and Prometheus metrics for failures, delayed attempts,
  and cache errors
- wire ConfigurationAuthLoginRateLimit with defaults (5 failures, 5m window,
  1s delay) and document it in conf/config.yaml
- integrate the limiter into the authn middleware, counting all Basic
  failures including /v2/, and honor request context cancellation
- add unit tests for threshold behavior, delay, and cancellation
- mark the login rate limit item complete in TODO.md
2026-09-13 12:54:54 +08:00
Tosone d2470bb310 build(deps): bump Go and web dependencies
Update direct and indirect Go module versions, including aws-sdk-go-v2,
goose, ClickHouse, Azure SDK and golang.org/x/exp, and refresh the web
toolchain (react 19.3, vite 8.3, typescript 7, shadcn, tailwind).

Switch the web Vite `@` alias from `__dirname` to `import.meta.dirname`
to align with the ESM config runtime.

Verification: not run (dependency-only change).
2026-09-12 17:16:41 +08:00
Tosone e361e401b0 chore(tools): invoke declared tools via go tool
Use the tools declared in go.mod's tool block (go-enum, addlicense,
swag, mockgen) through the `go tool` prefix, so they resolve via the
module tool directives instead of relying on globally installed
binaries:

- rewrite //go:generate mockgen/go-enum directives to
  `go tool mockgen` / `go tool go-enum` (42 source files)
- switch the Makefile addlicense target to `go tool addlicense`
- regenerate GoMock files with `go generate ./...`, which updates
  the generated-by headers, fixes stale mock signatures, and drops
  the unused MockFactory from runtime_mocks.go

Verification:
- go tool lists go-enum/addlicense/swag/mockgen from go.mod
- go generate ./... completes on enums.go
- go build -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" \
    ./pkg/background/build/runtime ./pkg/dal/repository/analytics ./pkg/service/token
2026-09-12 11:07:51 +08:00
Tosone 720022de3e refactor(mocks): generate mocks into source packages
Move generated mocks out of the `mocks/` subpackages and into the
source packages as `*_mocks.go` files for `pkg/distribution/clients`
and `pkg/service/password`, updating the go:generate directives to
emit `-package=clients` / `-package=password`. Update the import in
`pkg/service/users/users_test.go` to reference the new location.

Also:
- add `go.uber.org/mock/mockgen` to the tool directives and refresh
  module dependencies
- bump CI service images (mysql 9, postgres 18-alpine) and drop the
  removed mocks packages from the coverage exclusion list
- clean up .gitignore and ignore local tool artifacts (.pi/,
  skills-lock.json)

Verification:
- go vet -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./pkg/service/users/ ./pkg/service/password/ ./pkg/distribution/clients/
- go test -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./pkg/service/users/
2026-09-11 00:19:17 +08:00
Tosone 476df70a60 refactor: replace authz self-built cache with shared infra Cacher
Replace the hand-rolled authz cache (sync.RWMutex + map + dual-index
namespace cache) with the shared pkg/infra/cache Cacher, matching the
existing namespace_cache / repository_cache pattern.

- Inject Config and RedisClientFactory into the authorizer and build the
  Cachers via cacher.NewWithOptions in NewAuthorizer (now returns
  (Authorizer, error))
- Use read-through Cachers for role and namespace lookups; represent
  non-members with negative caching instead of the empty-string sentinel
- Keep the 30s TTL to preserve multi-instance eventual consistency, while
  gaining LRU 2Q, singleflight and an optional Redis backend
- Drop pkg/authz/cache.go and rewrite the cache tests as construction
  tests (inmemory success, redis-disabled failure)
- Document the New convenience wrapper in pkg/infra/cache/cacher.go

Verification: CI_DATABASE_TYPE=sqlite3 go test ./pkg/authz/... passes
2026-09-09 23:22:44 +08:00
Tosone 7594514d8b build: bump dependencies
- miniredis v2.38.0 -> v2.39.0
- aws-sdk-go-v2 v1.45.1 -> v1.46.0 (config, s3, and transitive sub-packages)
- docker/cli v29.7.2 -> v29.8.0
- gin-contrib/cors v1.7.7 -> v1.7.8, pprof v1.5.4 -> v1.5.5
- go-playground/validator v10.30.3 -> v10.30.4
- go-sql-driver/mysql v1.10.0 -> v1.10.1
- pgx/v5 v5.10.0 -> v5.11.0
- mcp-go v0.58.0 -> v1.0.0
- moby/buildkit v0.32.2 -> v0.33.0
- podman/v6 v6.1.0 -> v6.1.1
- golang.org/x/crypto, net, oauth2, sync (and transitive x/* packages)
- resty.dev/v3 v3.0.0-rc.3 -> v3.0.0-rc.4
- distribution-spec/specs-go refresh
- plus assorted transitive dependency bumps

Verification: go.sum regenerated to match go.mod
2026-09-09 21:59:31 +08:00
Tosone 4934a7061a build(deps): update all indirect and direct go module versions
Update all direct and indirect Go module dependencies to their latest compatible versions, including security patches and feature updates across the codebase.
2026-08-28 11:09:57 +08:00
Tosone c9ac979c95 refactor: migrate json encoding to json/v2 package across codebase
Replace all usages of standard encoding/json with encoding/json/v2 and jsontext
where applicable, update decoding logic to use json.UnmarshalRead and
json.MarshalWrite instead of manual encoder/decoder instances.

Verification:
go test -race ./pkg/... ./cmd/...
2026-08-27 14:28:01 +08:00