9 Commits
Author SHA1 Message Date
Tosone 5c05104720 feat(coderepos): read branches on demand and track provider push time
A sync listed the branches of every repository it saw, one API call per
repository per page. For an account with a few hundred repositories that
alone exhausts the GitHub rate limit, and the result was stale the moment a
branch was pushed.

Store the provider's push time instead, and read branches only when a build
form asks for them:

- the daemon reconciles repositories and owners only; github, gitlab and
  gitea no longer page through branches, diffBranch is gone, and the
  code_repository_branches table and model are dropped from the baseline
- CodeRepository gains pushed_at, filled from github pushed_at, gitlab
  last_activity_at (falling back to updated_at) and gitea updated_at, and
  the list orders by it so "most recently active" means the provider's view
  rather than our own row's updated_at, which every sync touched
- ListCodeRepositoryBranches and GetCodeRepositoryBranch resolve the
  binding, the decrypted token and the repository, then query the provider,
  so branch names are always current; a repository id is user input and is
  now checked against the caller's binding instead of exposing another
  account's repository
- the list response also stops filling updated_at from created_at

Existing installations need the new column and the dropped table applied by
hand, as documented for the baseline migration edit.

Verification:
- go build -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./...
- CI_DATABASE_TYPE=turso go test -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./pkg/dal/repository/coderepo/... ./pkg/service/coderepos/... ./pkg/server/handlers/coderepos/... ./pkg/background/daemon/coderepo/...
- make gormgen
- make swagen
2026-10-27 22:47:28 +08:00
Tosone 93de2dac54 fix(coderepos): stop the credential validator from panicking
PUT /api/v1/coderepos/{provider}/credential returned a 500 and logged
"http: panic serving ...: Bad field type *string": validator's max tag
panics when it is combined with required_if on a pointer field. A token
request leaves ssh_key, username and password nil, required_if passes
because the condition is false, the chain moves on to max, and max receives
the nil *string without dereferencing it.

Enforce the size limits in the service instead, next to the required checks
that already lived there, and keep required_if on the request so an
incomplete body is still rejected before it reaches the service. Swagger no
longer advertises maxLength for these fields.

Add a binding test that drives the three credential shapes through
server.WrapRequest, which is the path the panic was reached on.

Verification:
- CI_DATABASE_TYPE=turso go test -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./pkg/server/handlers/coderepos/... ./pkg/service/coderepos/...
- golangci-lint run --build-tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./pkg/api/... ./pkg/service/coderepos/... ./pkg/server/handlers/coderepos/...
- make swagen
2026-10-27 21:26:39 +08:00
Tosone 5ca747ddd7 refactor(oauth2): stop persisting OAuth tokens on login
The callback stored the access and refresh token on user_3rdparty and
re-issued the code repository sync on every login, which only worked
because the login refreshed an expiring token. Credentials now live in the
clone credential table, so the tokens have no reader left.

- drop the token update on repeated login and the token fields from both
  binding-creation paths; Oauth2UserInfo no longer carries them
- stop publishing a sync task when a binding is created: there is no
  credential at that point, so the task could only report a failure
- derive the GitLab and Gitea OAuth endpoints from scm.providers[].baseUrl
  instead of hardcoding gitlab.com, and point Gitea at its own
  /login/oauth endpoints and redirect callback

Verification:
- CI_DATABASE_TYPE=turso go test -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./pkg/service/oauth2/...
2026-10-27 21:07:40 +08:00
Tosone a80519d86f feat(coderepos): configure a per-provider SCM credential
Users had no way to supply their own access token: the only credential in
play was the OAuth token captured at login, which expires and which the
builders then copied into their own table. The clone credential table
existed but had no write path, so every lookup fell back to that token.

Give each provider an explicit credential:

- GET/PUT/DELETE /api/v1/coderepos/{provider}/credential plus
  POST .../credential/validate; the read endpoint returns a masked token and
  "has" flags, never the secret
- UpsertCodeRepositoryCredential validates a token against the provider,
  resolves the account id from it, ensures the third-party binding exists
  (409 when the account already belongs to another user) and seals
  token/ssh_key/password before storing them
- only token credentials can list repositories: ssh and username/password
  are clone credentials, so validate reports validated=false for them and
  no sync is queued
- ListCodeRepositoryProviders returns the configured providers joined with
  the caller's binding, credential and last sync state, so a provider that
  is configured but not linked yet is still offered by the UI
- fix the AccountID and UpdatedAt mistakes in the user3rdparty response,
  which dereferenced a nil pointer and reported the creation time twice
- regenerate the coderepos and user repository mocks and the operator
  swagger spec

Verification:
- make gormgen
- make swagen
- CI_DATABASE_TYPE=turso go test -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./pkg/service/coderepos/... ./pkg/server/handlers/coderepos/...
2026-10-27 21:07:37 +08:00
Tosone ffe28bb78e refactor(api): rename UserStatus Deactive to Inactive
"Deactive" is not a valid English word; the standard antonym of "Active"
is "Inactive". Restore the enum value, regenerate the go-enum output,
update the CLI test expectation, sync the generated swagger enum and
x-enum-varnames, and fix the web UI request payload and label.

Note: persisted rows and API clients using the old "Deactive" value must
switch to "Inactive"; no data migration is included.

Verification:
- go build -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./...
- go vet -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./pkg/api/enums/... ./cmd/cli/...
- CI_DATABASE_TYPE=turso go test -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./pkg/server/validators/...
2026-10-07 20:56:24 +08:00
Tosone d2f02d1db4 refactor(api): rename user status inactive to deactive
Rename the UserStatus enum value Inactive to Deactive, regenerate the
go-enum output, update the CLI test expectation and sync the generated
swagger enum and x-enum-varnames.

Verification:
- go build -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./...
- go test -tags "..." ./cmd/cli/... ./pkg/server/validators/...
2026-10-04 16:34:58 +08:00
Tosone 3958a6b61d docs(swagger): align handler API annotations with implementation
Fix and complete Swagger annotations for the HTTP handlers so the
generated OpenAPI spec matches the registered routes and request
types:

- Correct path parameter types from number/int64 to string, since all
  resource IDs are UUID strings.
- Fix wrong router paths and methods (builders, coderepos, tags,
  webhooks, users, validators) and add missing path parameters.
- Fix request/response schema references (builder runner list, oauth2
  callback, webhook get/log) and a few summary/description typos.
- Add annotations for previously undocumented endpoints: artifacts,
  analytics, builder runner actions, and user self/signup/recovery.
- Rename the users and coderepos path parameters to user_id/repo_id and
  align the route registrations and request struct tags accordingly;
  mark BuilderRunnerItem.Log as swaggertype string so swag can parse it.
- Regenerate tools/skill/sigma-api-operator/swagger.yaml. The
  distribution handlers are intentionally left undocumented.

Verification:
- go test -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./pkg/server/handlers/users/ ./pkg/server/handlers/coderepos/ -run TestInitialize -count=1
- go tool swag fmt && go tool swag init --output tools/skill/sigma-api-operator --outputTypes yaml
- go build -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./pkg/server/handlers/... ./pkg/api/...
- gofmt -l pkg/server/handlers pkg/api
2026-10-03 21:51:37 +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 c4ecfa80d9 chore: initial commit 2026-08-01 20:32:49 +08:00