Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Merging 11 PRs #1326

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
jonnii merged 12 commits into main from stack-merge-stack-1782266218
Jun 24, 2026
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
12 commits
Select commit Hold shift + click to select a range
2859eac
refactor(web): remove sample alice/bob stacks from repo provider
jonnii Jun 23, 2026
2058eb5
feat(server): drive deploy posture from STACKIT_ENV, not $PORT
jonnii Jun 23, 2026
4a1cacf
refactor(api): extract Syncer.SyncRepo for per-repo sync triggers
jonnii Jun 23, 2026
a6615d1
feat(api): add GitHub webhook signature + push parsing helper
jonnii Jun 23, 2026
d817de5
feat(api): add GitHub webhook receiver for evented refresh
jonnii Jun 23, 2026
9bc7342
feat(api): coalesce webhook-driven syncs per repo
jonnii Jun 23, 2026
116cfbb
feat(api): add manual sync endpoint for on-demand refresh
jonnii Jun 23, 2026
0a8ec1d
feat(server): default sync interval to 5m and document evented refresh
jonnii Jun 23, 2026
8e72099
feat(server): index repos by owner/repo for GitHub-style routes
jonnii Jun 23, 2026
33aa410
feat(server): serve repos at /repos/{owner}/{repo} path routes
jonnii Jun 23, 2026
f4d08e3
feat(web): GitHub-style path URLs for repos, branches, stacks, PRs
jonnii Jun 23, 2026
d61e5f9
Consolidate stack [stack] (11 branches)
jonnii Jun 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions .env.template
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
# `mise run dev:server` load .env via the [env] block in mise.toml, so the
# values flow into the server process automatically.
#
# Required only when running in "public mode" — i.e. when $PORT or
# $STACKIT_PUBLIC is set (Railway, Fly, Heroku, etc). For purely local
# development (`mise run dev`), every STACKIT_GITHUB_* / STACKIT_SESSION_KEY
# / STACKIT_ALLOWED_GH_* variable can stay blank and the server will start
# with auth disabled.
# Required only in production (STACKIT_ENV=production, e.g. Railway, Fly,
# Heroku), which binds 0.0.0.0 and requires auth (or -read-only). For purely
# local development (`mise run dev`, the default STACKIT_ENV=local), every
# STACKIT_GITHUB_* / STACKIT_SESSION_KEY / STACKIT_ALLOWED_GH_* variable can
# stay blank and the server binds loopback with auth disabled.

# --- GitHub OAuth app (https://github.com/settings/developers) ----------------
# Create an OAuth App with:
Expand Down Expand Up @@ -37,12 +37,14 @@ STACKIT_ALLOWED_GH_ORG=
# Required when -repos-config entries use owner+name instead of an absolute path.
STACKIT_REPOS_ROOT=

# --- Public mode override (rare) ----------------------------------------------
# Set non-empty to force public-mode behavior (binds 0.0.0.0, requires auth)
# even without $PORT. Leave blank for local dev.
# STACKIT_PUBLIC=
# --- Deployment posture -------------------------------------------------------
# `local` (default) binds 127.0.0.1 with auth optional — leave it unset for dev.
# `production` binds 0.0.0.0, emits JSON logs, forces Secure cookies, honors
# $PORT, and requires auth (or -read-only). Set it on hosted deploys.
# STACKIT_ENV=production

# --- Port override ------------------------------------------------------------
# PaaS hosts inject $PORT automatically; set it here only if running the
# binary directly without `mise run dev`.
# Only honored in production (PaaS hosts inject $PORT automatically). Ignored
# in local, so a stray $PORT in your shell can't move the dev listener; pass
# `-port` to the binary instead.
# PORT=8080
217 changes: 172 additions & 45 deletions api/openapi/stackit.yaml
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,54 @@ info:
servers:
- url: /
paths:
/api/v1/view:
/api/v1/repos:
get:
summary: List repositories the server is serving (filtered to the caller).
operationId: listRepos
responses:
"200":
description: Repository index.
content:
application/json:
schema:
$ref: "#/components/schemas/ReposListResponse"
post:
summary: Onboard a GitHub repository (clone and start serving it).
description: >
Clones a GitHub repository the authenticated user can access and starts
serving it, recorded against that user so only they see it. Requires an
authenticated, writable, DB-backed server with a repos root configured;
read-only servers refuse with 405.
operationId: onboardRepo
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/OnboardRepoRequest"
responses:
"201":
description: The newly served repository.
content:
application/json:
schema:
$ref: "#/components/schemas/RepoSummary"
"400":
description: Missing or invalid owner/name.
"401":
description: Authentication required.
"404":
description: Repository not found or not accessible to the caller.
"405":
description: Server is read-only.
"409":
description: Repository already onboarded.
"503":
description: Onboarding not available (no auth, database, or repos root).
/api/v1/repos/{owner}/{repo}/view:
parameters:
- $ref: "#/components/parameters/Owner"
- $ref: "#/components/parameters/Repo"
get:
summary: Combined view payload for the dashboard.
operationId: getView
Expand All @@ -17,7 +64,12 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/ViewResponse"
/api/v1/repo:
"404":
description: Repository not found or not visible to the caller.
/api/v1/repos/{owner}/{repo}/repo:
parameters:
- $ref: "#/components/parameters/Owner"
- $ref: "#/components/parameters/Repo"
get:
summary: Repository metadata.
operationId: getRepo
Expand All @@ -28,7 +80,12 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/RepoResponse"
/api/v1/stacks:
"404":
description: Repository not found or not visible to the caller.
/api/v1/repos/{owner}/{repo}/stacks:
parameters:
- $ref: "#/components/parameters/Owner"
- $ref: "#/components/parameters/Repo"
get:
summary: List discovered stacks.
operationId: listStacks
Expand All @@ -41,7 +98,10 @@ paths:
type: array
items:
$ref: "#/components/schemas/StackSummary"
/api/v1/stacks/{rootBranch}:
/api/v1/repos/{owner}/{repo}/stacks/{rootBranch}:
parameters:
- $ref: "#/components/parameters/Owner"
- $ref: "#/components/parameters/Repo"
get:
summary: Get detailed stack by root branch.
operationId: getStack
Expand All @@ -60,7 +120,46 @@ paths:
$ref: "#/components/schemas/StackDetail"
"404":
description: Stack not found.
/api/v1/branches:
/api/v1/repos/{owner}/{repo}/stacks/{rootBranch}/submit:
parameters:
- $ref: "#/components/parameters/Owner"
- $ref: "#/components/parameters/Repo"
post:
summary: Submit a stack as stacked pull requests.
operationId: submitStack
parameters:
- in: path
name: rootBranch
required: true
schema:
type: string
responses:
"200":
description: Submit result.
"404":
description: Stack not found.
"405":
description: Server is read-only.
/api/v1/repos/{owner}/{repo}/sync:
parameters:
- $ref: "#/components/parameters/Owner"
- $ref: "#/components/parameters/Repo"
post:
summary: Force an immediate refresh of one repository.
operationId: syncRepo
responses:
"204":
description: Refresh completed.
"404":
description: Repository not found or not visible to the caller.
"405":
description: Server is read-only.
"502":
description: Mirror fetch failed.
/api/v1/repos/{owner}/{repo}/branches:
parameters:
- $ref: "#/components/parameters/Owner"
- $ref: "#/components/parameters/Repo"
get:
summary: List tracked branches.
operationId: listBranches
Expand All @@ -73,7 +172,10 @@ paths:
type: array
items:
$ref: "#/components/schemas/BranchResponse"
/api/v1/branches/{branchName}:
/api/v1/repos/{owner}/{repo}/branches/{branchName}:
parameters:
- $ref: "#/components/parameters/Owner"
- $ref: "#/components/parameters/Repo"
get:
summary: Get one tracked branch.
operationId: getBranch
Expand All @@ -92,13 +194,16 @@ paths:
$ref: "#/components/schemas/BranchResponse"
"404":
description: Branch not found.
/api/v1/branch-diff:
/api/v1/repos/{owner}/{repo}/branch-diff/{branchName}:
parameters:
- $ref: "#/components/parameters/Owner"
- $ref: "#/components/parameters/Repo"
get:
summary: Get raw patch diff for a tracked branch.
operationId: getBranchDiff
parameters:
- in: query
name: branch
- in: path
name: branchName
required: true
schema:
type: string
Expand All @@ -110,10 +215,13 @@ paths:
schema:
$ref: "#/components/schemas/BranchDiffResponse"
"400":
description: Missing branch query parameter.
description: Missing branch.
"404":
description: Branch not found.
/api/v1/events:
/api/v1/repos/{owner}/{repo}/events:
parameters:
- $ref: "#/components/parameters/Owner"
- $ref: "#/components/parameters/Repo"
get:
summary: Server-sent event stream for repository refresh events.
operationId: streamEvents
Expand All @@ -124,51 +232,66 @@ paths:
text/event-stream:
schema:
type: string
/api/v1/repos:
get:
summary: List repositories the server is serving (filtered to the caller).
operationId: listRepos
responses:
"200":
description: Repository index.
content:
application/json:
schema:
$ref: "#/components/schemas/ReposListResponse"
/api/v1/webhooks/github:
post:
summary: Onboard a GitHub repository (clone and start serving it).
description: >
Clones a GitHub repository the authenticated user can access and starts
serving it, recorded against that user so only they see it. Requires an
authenticated, writable, DB-backed server with a repos root configured;
read-only servers refuse with 405.
operationId: onboardRepo
summary: Receive a GitHub webhook delivery and trigger a repo refresh.
description: >-
Authenticated solely by the X-Hub-Signature-256 HMAC over the raw body;
it carries no session or CSRF token. Fails closed: when no webhook secret
is configured the endpoint returns 404. A verified push is acked
immediately and the matching managed repo is mirror-fetched off the
request path (a burst for one repo coalesces into a single fetch). It is
unaffected by read-only mode, since a refresh is a read-side operation.
operationId: receiveGitHubWebhook
parameters:
- in: header
name: X-Hub-Signature-256
required: true
description: HMAC-SHA256 of the raw request body, keyed by the webhook secret.
schema:
type: string
- in: header
name: X-GitHub-Event
required: true
description: GitHub event name; only "push" triggers a refresh and "ping" is acked.
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/OnboardRepoRequest"
type: object
description: The GitHub webhook event payload (e.g. a push event).
responses:
"201":
description: The newly served repository.
content:
application/json:
schema:
$ref: "#/components/schemas/RepoSummary"
"202":
description: Push accepted; a refresh is scheduled for the matching managed repo.
"204":
description: >-
Verified but no action taken — a ping, a non-push event, or a push
that did not resolve to a managed repo.
"400":
description: Missing or invalid owner/name.
description: Could not read the request body.
"401":
description: Authentication required.
description: Missing or invalid signature.
"404":
description: Repository not found or not accessible to the caller.
"405":
description: Server is read-only.
"409":
description: Repository already onboarded.
"503":
description: Onboarding not available (no auth, database, or repos root).
description: Webhook receiver is disabled (no secret configured).
components:
parameters:
Owner:
in: path
name: owner
required: true
description: GitHub repository owner (login), matched case-insensitively.
schema:
type: string
Repo:
in: path
name: repo
required: true
description: GitHub repository name, matched case-insensitively.
schema:
type: string
schemas:
ViewResponse:
type: object
Expand Down Expand Up @@ -373,6 +496,10 @@ components:
properties:
id:
type: string
owner:
type: string
repo:
type: string
displayName:
type: string
trunk:
Expand Down
Loading
Loading

AltStyle によって変換されたページ (->オリジナル) /