Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh

Commit

A workflow step can open a g1t.page build with POST /repos/{owner}/{repo}/deployments/builds (the workflow tool's start_deployment_build over MCP), sending its job's own token and, optionally, the project's slug and the commit; the project may be left out when the repository has one project with Deployments on. It answers with the build's id and token for g1t-runner deploy, whether it is production or a preview, the app's address, whether the run was trusted, the project's root directory, build command and output directory, and the variables and secrets builds of that kind get. It needs deployments:write, which a job's permissions give with deployments: write or pages: write, and no token but a job's is let through. The API reference, its example, and the MCP reference say so.

Claude-Session:
https://claude.ai/code/session_01PnwTRSNaC7vEHTAuBzjhrn
Claudeagent and Claudeagentcommitted Parentd0cffa8Browse files
10 files+72−30/10 viewed
+33−2
2424 CreateDeploymentStatus,
2525 ListEnvironments,
2626 GetEnvironment,
27+ StartDeploymentBuild,
2728 }
2829
2930 /// The states a deployment's status can have.
3334 /// Every one: `Op::ALL` lists each as `Op::Deployments(…)`, which a
3435 /// test checks against this.
3536 #[cfg(test)]
36− pub const ALL: [DeploymentsOp; 7] = [
37+ pub const ALL: [DeploymentsOp; 8] = [
3738 DeploymentsOp::ListDeployments,
3839 DeploymentsOp::GetDeployment,
3940 DeploymentsOp::CreateDeployment,
4142 DeploymentsOp::CreateDeploymentStatus,
4243 DeploymentsOp::ListEnvironments,
4344 DeploymentsOp::GetEnvironment,
45+ DeploymentsOp::StartDeploymentBuild,
4446 ];
4547
4648 pub fn name(self) -> &'static str {
5254 DeploymentsOp::CreateDeploymentStatus => "create_deployment_status",
5355 DeploymentsOp::ListEnvironments => "list_environments",
5456 DeploymentsOp::GetEnvironment => "get_environment",
57+ DeploymentsOp::StartDeploymentBuild => "start_deployment_build",
5558 }
5659 }
5760
6568 DeploymentsOp::CreateDeploymentStatus => "Create a deployment status",
6669 DeploymentsOp::ListEnvironments => "List environments",
6770 DeploymentsOp::GetEnvironment => "Get an environment",
71+ DeploymentsOp::StartDeploymentBuild => "Start a g1t.page build from a workflow",
6872 }
6973 }
7074
7781 DeploymentsOp::CreateDeploymentStatus => "Add a status to a reported deployment: state (queued, in_progress, success, failure, error or inactive), description, environment_url (where it is served) and log_url (where its output can be read). The deployment takes its state, and any address it gives. A success with auto_inactive (true unless you say) makes the environment's older successful deployments inactive. The commit's `deploy / <environment>` check follows: pending while queued or in progress, then success, failure or error. A g1t.page build's statuses come from the build and cannot be added to. Needs the Write role.",
7882 DeploymentsOp::ListEnvironments => "List the environments a repository's deployments went to, those people use directly first (production by name before others), then the most recently deployed, and after them those with protection rules but no deployment yet. Each has its name, url (where its current deployment is served), production_environment, transient_environment, deployments_count, latest (its newest deployment, whatever its state), current (its newest successful deployment that is still active) and updated_at, and, when it has rules, protection_rules (required_reviewers, wait_timer, branch_policy), deployment_branch_policy, branch_policies and can_admins_bypass. total_count counts deployments across every environment. Needs the Read role.",
7983 DeploymentsOp::GetEnvironment => "Get one environment by name, matched without regard to case, with its current and latest deployments and its protection rules (see update_environment). An environment with rules but no deployment yet is found too. A name with slashes is URL-encoded in the path. Needs the Read role.",
84+ DeploymentsOp::StartDeploymentBuild => "From a running g1t Actions job, open a g1t.page build of one of the repository's projects, which the job then builds in its own checkout with `g1t-runner deploy` (the g1t/deploy action does both). Only the job's own token (G1T_TOKEN) may call it, with `deployments: write` (or `pages: write`) in its `permissions:`. project is the project's slug; it may be left out when the repository has one project with Deployments on. The run decides what is built: a run on the project's production branch (a push, a dispatch or a schedule there) builds production, a pull request's run builds that pull request's preview, and a run on another branch builds that branch's preview; a tag's run is refused. sha is the commit built, the run's unless you say. A pull request from a fork or from someone without the Write role, and a run that had to be approved, get no build secrets. The workspace's plan must include Deployments and its spend limit must not be reached; the build's time is the job's Actions time and is not charged again. Returns deploy_id and token (DEPLOY_ID and DEPLOY_TOKEN for `g1t-runner deploy`, the token good for this build alone until it finishes), kind (production or preview), project, branch, number, commit, url (the app's address), trusted, the project's root_dir, build_command and output_dir, and build_env and build_secrets (the project's variables and secrets for builds of that kind). The commit's `g1t / deploy` check is pending until the build reports.",
8085 }
8186 }
8287
8388 /// Whether it changes anything.
8489 pub fn writes(self) -> bool {
85− matches!(self, DeploymentsOp::CreateDeployment | DeploymentsOp::CreateDeploymentStatus)
90+ matches!(
91+ self,
92+ DeploymentsOp::CreateDeployment | DeploymentsOp::CreateDeploymentStatus | DeploymentsOp::StartDeploymentBuild
93+ )
8694 }
8795
8896 pub fn input(self) -> Value {
137145 &["repo", "id", "state"],
138146 ),
139147 DeploymentsOp::ListEnvironments => (json!({ "repo": repo }), &["repo"]),
148+ DeploymentsOp::StartDeploymentBuild => (
149+ json!({
150+ "repo": repo,
151+ "project": { "type": "string", "description": "The project's slug; may be left out when the repository has one project with Deployments on." },
152+ "sha": { "type": "string", "description": "The commit built, in hex; the run's commit unless you say." },
153+ }),
154+ &["repo"],
155+ ),
140156 DeploymentsOp::GetEnvironment => (
141157 json!({
142158 "repo": repo,
236252 "create_deployment_status"
237253 }
238254 DeploymentsOp::ListEnvironments => "list_environments",
255+ // The deployments service checks the job's token itself: the
256+ // caller (the job's workspace, with `token.job`) is the actor.
257+ DeploymentsOp::StartDeploymentBuild => {
258+ for key in ["project", "sha"] {
259+ if let Some(value) = input[key].as_str().map(str::trim).filter(|value| !value.is_empty()) {
260+ out.insert(key.into(), value.into());
261+ }
262+ }
263+ "start_from_workflow"
264+ }
239265 DeploymentsOp::GetEnvironment => {
240266 let name = input["environment"].as_str().map(str::trim).filter(|name| !name.is_empty()).ok_or("Name the environment.")?;
241267 out.insert("name".into(), name.into());
294320 assert!(super::args(DeploymentsOp::CreateDeploymentStatus, &json!({ "repo": "acme/web", "id": "dep_1" })).is_err());
295321 let (method, args) = super::args(DeploymentsOp::GetEnvironment, &json!({ "repo": "acme/web", "environment": "review/x" })).unwrap();
296322 assert_eq!((method, args["name"].clone()), ("get_environment", json!("review/x")));
323+ let (method, args) = super::args(DeploymentsOp::StartDeploymentBuild, &json!({ "repo": "acme/web", "project": " web ", "sha": "" })).unwrap();
324+ assert_eq!(method, "start_from_workflow");
325+ assert_eq!(args["project"], json!("web"));
326+ assert!(!args.contains_key("sha"), "an empty sha is the run's");
327+ assert!(DeploymentsOp::StartDeploymentBuild.writes());
297328 }
298329
299330 #[test]
+1−0
460460 Op::Deployments(DeploymentsOp::CreateDeploymentStatus),
461461 Op::Deployments(DeploymentsOp::ListEnvironments),
462462 Op::Deployments(DeploymentsOp::GetEnvironment),
463+ Op::Deployments(DeploymentsOp::StartDeploymentBuild),
463464 ],
464465 ),
465466 (
+2−1
707707 }
708708
709709 impl Op {
710− pub const ALL: [Op; 350] = [
710+ pub const ALL: [Op; 351] = [
711711 Op::Whoami,
712712 Op::GetWorkspace,
713713 Op::CreateWorkspace,
983983 Op::Deployments(DeploymentsOp::CreateDeploymentStatus),
984984 Op::Deployments(DeploymentsOp::ListEnvironments),
985985 Op::Deployments(DeploymentsOp::GetEnvironment),
986+ Op::Deployments(DeploymentsOp::StartDeploymentBuild),
986987 Op::Artifacts(ArtifactsOp::ListArtifacts),
987988 Op::Artifacts(ArtifactsOp::ListRunArtifacts),
988989 Op::Artifacts(ArtifactsOp::GetArtifact),
+30−0
1056710567 },
1056810568 "notes": "Production comes first, then the most recently deployed. `latest` is the newest deployment whatever its state; `current` is the newest that succeeded and is still active, and `url` is where it is served."
1056910569 },
10570+ "start_deployment_build": {
10571+ "params": {
10572+ "owner": "flagon-io",
10573+ "name": "hello"
10574+ },
10575+ "request": {
10576+ "project": "hello"
10577+ },
10578+ "response": {
10579+ "deploy_id": "dpl_01kq9c4e6g8j0m2p4r6t8v0x2z",
10580+ "token": "…",
10581+ "kind": "preview",
10582+ "project": "hello",
10583+ "branch": "new-header",
10584+ "number": 42,
10585+ "commit": "9f2c4e6a8b0d1f3e5a7c9b1d3f5e7a9c0b2d4f6e",
10586+ "url": "https://hello-git-new-header-flagonio.g1t.page",
10587+ "trusted": true,
10588+ "root_dir": "",
10589+ "build_command": null,
10590+ "output_dir": null,
10591+ "build_env": {
10592+ "PUBLIC_API_URL": "https://api.example.com"
10593+ },
10594+ "build_secrets": {
10595+ "SENTRY_AUTH_TOKEN": "…"
10596+ }
10597+ },
10598+ "notes": "Called from a workflow step with the job's own token, `${{ github.token }}`, in a job with `permissions: deployments: write`; the [`g1t/deploy`](/guides/deployments/#deploying-from-a-workflow) action calls it, masks the token and the secrets, and runs `g1t-runner deploy` with them. Any other token is refused. This is a pull request's run, so it builds the pull request's preview; the same workflow on the production branch builds production. See [Deploying from a workflow](/guides/deployments/#deploying-from-a-workflow)."
10599+ },
1057010600 "get_environment": {
1057110601 "params": {
1057210602 "owner": "flagon-io",
+2−0
359359 &[("environment", "environment"), ("ref", "ref"), ("sha", "sha"), ("task", "task"), ("state", "state"), ("source", "source"), ("creator", "creator"), ("page", "page"), ("per_page", "per_page")],
360360 ),
361361 route("POST", "/repos/:owner/:name/deployments", Op::Deployments(DeploymentsOp::CreateDeployment), &[]),
362+ // A g1t Actions job opening a g1t.page build it runs itself.
363+ route("POST", "/repos/:owner/:name/deployments/builds", Op::Deployments(DeploymentsOp::StartDeploymentBuild), &[]),
362364 route("GET", "/repos/:owner/:name/deployments/:id", Op::Deployments(DeploymentsOp::GetDeployment), &[]),
363365 route("GET", "/repos/:owner/:name/deployments/:id/statuses", Op::Deployments(DeploymentsOp::ListDeploymentStatuses), &[]),
364366 route("POST", "/repos/:owner/:name/deployments/:id/statuses", Op::Deployments(DeploymentsOp::CreateDeploymentStatus), &[]),
+1−0
263263 a("create_deployment_status", Op::Deployments(DeploymentsOp::CreateDeploymentStatus), "Report where a deployment is: in_progress, success, failure"),
264264 a("list_environments", Op::Deployments(DeploymentsOp::ListEnvironments), "Environments with their current and latest deployments"),
265265 a("get_environment", Op::Deployments(DeploymentsOp::GetEnvironment), "One environment by name, with its protection rules"),
266+ a("start_deployment_build", Op::Deployments(DeploymentsOp::StartDeploymentBuild), "From a workflow job: open a g1t.page build it runs itself"),
266267 a("update_environment", Op::Protection(ProtectionOp::UpdateEnvironment), "Set an environment's reviewers, wait timer and branches"),
267268 a("delete_environment", Op::Protection(ProtectionOp::DeleteEnvironment), "Remove an environment's protection rules"),
268269 a("pending_deployments", Op::Protection(ProtectionOp::GetPendingDeployments), "The environments holding a run's jobs"),
+1−0
464464 | [`create_deployment_status`](/reference/api/deployments/create-deployment-status/) | Report where a deployment is: `state` (`queued`, `in_progress`, `success`, `failure`, `error` or `inactive`), with optional `description`, `environment_url`, `log_url` and `auto_inactive`. Not for a g1t.page build. Write role. | `repo`, `id`, `state` | `deployments:write` |
465465 | [`list_environments`](/reference/api/deployments/list-environments/) | Environments with their address, current and latest deployments, production first. | `repo` | `deployments:read` |
466466 | [`get_environment`](/reference/api/deployments/get-environment/) | One environment by name, with its protection rules. | `repo`, `environment` | `deployments:read` |
467+| [`start_deployment_build`](/reference/api/deployments/start-deployment-build/) | From a running workflow job, with the job's own token only: open a g1t.page build of a `project` (optional when the repository has one with Deployments on) that the job builds itself with `g1t-runner deploy`, optionally at `sha`. Production for a run on the production branch, a preview otherwise. Returns `deploy_id`, `token`, `kind`, `url`, `build_env` and `build_secrets`. See [deploying from a workflow](/guides/deployments/#deploying-from-a-workflow). | `repo` | `deployments:write` |
467468 | [`update_environment`](/reference/api/run-protection/update-environment/) | Set an environment's [protection rules](/guides/actions/#environments): `reviewers` (up to 6, `{"type": "User" or "Team", "name"}`), `prevent_self_review`, `wait_timer` (minutes), `deployment_branch_policy`, `branch_policies` and `can_admins_bypass`. Admin role. | `repo`, `environment` | `repo:admin` |
468469 | [`delete_environment`](/reference/api/run-protection/delete-environment/) | Remove an environment's protection rules; its secrets and deployments stay. Admin role. | `repo`, `environment` | `repo:admin` |
469470 | [`pending_deployments`](/reference/api/run-protection/get-pending-deployments/) | The environments holding a run's jobs: their state, reviewers, wait timer, jobs, and whether you may approve. | `repo`, `id` | `workflows:read` |
+0−0

Binary or large file; its contents are not shown.

+1−0
11421142 ("get_environment", Scope::DeploymentsRead),
11431143 ("create_deployment", Scope::DeploymentsWrite),
11441144 ("create_deployment_status", Scope::DeploymentsWrite),
1145+ ("start_deployment_build", Scope::DeploymentsWrite),
11451146 // What keeps runs safe: the runs environments hold and reviewing them,
11461147 // approving a pull request's run, and a repository's own rules for
11471148 // its environments and tokens, which are an admin's.
+1−0
516516 ["get_environment", "deployments:read"],
517517 ["create_deployment", "deployments:write"],
518518 ["create_deployment_status", "deployments:write"],
519+ ["start_deployment_build", "deployments:write"],
519520 // What keeps runs safe: the runs environments hold and reviewing them,
520521 // approving a pull request's run, and a repository's own rules for its
521522 // environments and tokens, which are an admin's.

Comments

Sign in to comment.