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

Merge branch 'worktree-agent-a4db4b523bb973765'

# Conflicts: # apps/api/src/operations.rs # crates/g1t/src/commands/mod.rs # crates/g1t/tests/cli.rs

syntaqxcommitted Parents3a656dc3077a27Browse files
23 files+303−47 files not counted0/23 viewed
+2−0
418418 "GitHub Actions workflows in .g1t/workflows, their runs, their jobs' logs, their artifacts, and the repository's actions/cache entries.",
419419 &[
420420 Op::ListWorkflows,
421+ Op::GetWorkflow,
421422 Op::ListWorkflowRuns,
422423 Op::GetWorkflowRun,
423424 Op::GetJobLogs,
713714 Op::ListWebhookDeliveries => "List webhook deliveries",
714715 Op::RedeliverWebhook => "Redeliver a webhook delivery",
715716 Op::ListWorkflows => "List workflows",
717+ Op::GetWorkflow => "Get a workflow",
716718 Op::ListWorkflowRuns => "List workflow runs",
717719 Op::GetWorkflowRun => "Get a workflow run",
718720 Op::GetJobLogs => "Get a job's log",
+23−1
211211 ListWebhookDeliveries,
212212 RedeliverWebhook,
213213 ListWorkflows,
214+ GetWorkflow,
214215 ListWorkflowRuns,
215216 GetWorkflowRun,
216217 GetJobLogs,
696697 }
697698
698699 impl Op {
699− pub const ALL: [Op; 371] = [
700+ pub const ALL: [Op; 372] = [
700701 Op::Whoami,
701702 Op::GetWorkspace,
702703 Op::CreateWorkspace,
796797 Op::ListWebhookDeliveries,
797798 Op::RedeliverWebhook,
798799 Op::ListWorkflows,
800+ Op::GetWorkflow,
799801 Op::ListWorkflowRuns,
800802 Op::GetWorkflowRun,
801803 Op::GetJobLogs,
11761178 Op::ListWebhookDeliveries => "list_webhook_deliveries",
11771179 Op::RedeliverWebhook => "redeliver_webhook",
11781180 Op::ListWorkflows => "list_workflows",
1181+ Op::GetWorkflow => "get_workflow",
11791182 Op::ListWorkflowRuns => "list_workflow_runs",
11801183 Op::GetWorkflowRun => "get_workflow_run",
11811184 Op::GetJobLogs => "get_job_logs",
15461549 Op::ListWorkflows => {
15471550 "A repository's GitHub Actions workflows, read from .g1t/workflows (GitHub's format, so a repository moves by renaming .github to .g1t) on its default branch: the events that start each, whether it is on, any problem with its file, notes on anything that runs differently on g1t, its manual-run inputs, and its last run."
15481551 }
1552+ Op::GetWorkflow => {
1553+ "One workflow, named by its id, its file name (ci.yml), its path or its name (CI): what list_workflows says of it, with `source`, its file as written on `ref` (the default branch unless you give a branch or tag), and `ref`, the branch or tag read."
1554+ }
15491555 Op::ListWorkflowRuns => {
15501556 "A repository's workflow runs, newest first: of one workflow (its id or file name), a branch, an event, a pull request's number, or a commit."
15511557 }
25642570 ),
25652571 Op::ListWebhooks => object(hook_owner(json!({})), &[]),
25662572 Op::ListWorkflows => repo_only(),
2573+ Op::GetWorkflow => object(
2574+ json!({
2575+ "repo": repo_schema(),
2576+ "workflow": { "type": "string", "description": "The workflow's id, file name (ci.yml), path or name." },
2577+ "ref": { "type": "string", "description": "A branch or tag to read its file on. The default branch if not given." },
2578+ }),
2579+ &["repo", "workflow"],
2580+ ),
25672581 Op::ListWorkflowRuns => object(
25682582 json!({
25692583 "repo": repo_schema(),
46474661 .await
46484662 }
46494663 Op::ListWorkflows => pass(actions, "workflows", &json!({ "repo": repo, "viewer": viewer })).await,
4664+ Op::GetWorkflow => {
4665+ pass(
4666+ actions,
4667+ "workflow",
4668+ &json!({ "repo": repo, "viewer": viewer, "workflow": text(input, "workflow"), "ref": optional_text(input, "ref") }),
4669+ )
4670+ .await
4671+ }
46504672 Op::ListWorkflowRuns => {
46514673 pass(
46524674 actions,
+33−0
30553055 ],
30563056 "notes": "`state` is `active` or `disabled`. `dispatch` holds the `workflow_dispatch` inputs, or is `null` when the workflow cannot be run by hand. See [GitHub Actions](/guides/actions/)."
30573057 },
3058+ "get_workflow": {
3059+ "params": {
3060+ "workflow": "release.yml"
3061+ },
3062+ "query": {
3063+ "ref": "main"
3064+ },
3065+ "response": {
3066+ "id": "wfl_01kpw2c5d8e1f4g7h0j3k6m9nr",
3067+ "path": ".g1t/workflows/release.yml",
3068+ "name": "Release",
3069+ "events": [
3070+ "workflow_dispatch"
3071+ ],
3072+ "state": "active",
3073+ "error": null,
3074+ "notes": [],
3075+ "dispatch": {
3076+ "channel": {
3077+ "type": "choice",
3078+ "options": [
3079+ "beta",
3080+ "stable"
3081+ ],
3082+ "default": "beta"
3083+ }
3084+ },
3085+ "last_run": null,
3086+ "ref": "main",
3087+ "source": "name: Release\non:\n workflow_dispatch:\n inputs:\n channel:\n type: choice\n options: [beta, stable]\n default: beta\njobs:\n release:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n - run: ./scripts/release.sh ${{ inputs.channel }}\n"
3088+ },
3089+ "notes": "`workflow` is the workflow's id, file name, path or name. `source` is its file as written on `ref`; `404` when the file is not on that branch or tag."
3090+ },
30583091 "list_workflow_runs": {
30593092 "query": {
30603093 "workflow": "ci.yml",
+1−0
196196 through::<work::Pull>(op, sent)
197197 }
198198 Op::ListWorkflows => through::<Vec<actions::Workflow>>(op, sent),
199+ Op::GetWorkflow => through::<actions::WorkflowDetail>(op, sent),
199200 Op::ListWorkflowRuns => through::<Vec<actions::WorkflowRun>>(op, sent),
200201 Op::GetWorkflowRun => through::<actions::RunDetail>(op, sent),
201202 Op::GetJobLogs => through::<actions::JobLog>(op, sent),
+6−0
750750 ),
751751 route(
752752 "GET",
753+ "/repos/:owner/:name/actions/workflows/:workflow",
754+ Op::GetWorkflow,
755+ &[("ref", "ref")],
756+ ),
757+ route(
758+ "GET",
753759 "/repos/:owner/:name/actions/workflows/:workflow/runs",
754760 Op::ListWorkflowRuns,
755761 &[("branch", "branch"), ("event", "event"), ("per_page", "limit")],
+1−0
218218 default_action: None,
219219 actions: &[
220220 a("list", Op::ListWorkflows, "Workflows on the default branch"),
221+ a("get", Op::GetWorkflow, "One workflow by id, file or name, with its file on a branch or tag"),
221222 a("list_runs", Op::ListWorkflowRuns, "Runs, newest first"),
222223 a("get_run", Op::GetWorkflowRun, "One run with its jobs and steps; an earlier attempt with attempt"),
223224 a("job_logs", Op::GetJobLogs, "A job's log after a sequence number"),
+3−1
13001300
13011301 Open a repository's **Actions** page, in its sidebar. Pick a workflow to
13021302 see its runs, run it by hand if it has `workflow_dispatch`, or turn it off
1303−without touching its file.
1303+without touching its file. From a terminal, [`g1t workflow`](/guides/cli/#workflows)
1304+does the same.
13041305
13051306 A run's page opens on its **Summary**. Its sidebar lists **All jobs**;
13061307 pick one to see its steps and their logs as they are written. Groups
20192020 | `workflow` action | Route |
20202021 | --- | --- |
20212022 | `list` | `GET /repos/{owner}/{repo}/actions/workflows` |
2023+| `get` | `GET /repos/{owner}/{repo}/actions/workflows/{workflow}`, with `ref`: the workflow, with `source`, its file on that branch or tag |
20222024 | `list_runs` | `GET /repos/{owner}/{repo}/actions/runs`, with `workflow`, `branch`, `event`, `pull`, `head_sha` |
20232025 | `get_run` | `GET /repos/{owner}/{repo}/actions/runs/{id}` |
20242026 | `job_logs` | `GET /repos/{owner}/{repo}/actions/jobs/{job}/logs?after=`, or `?format=text` for the whole log as plain text |
+40−2
11 ---
22 title: The g1t CLI
3−description: Install the g1t command line, sign in, and work with repositories, issues, pull requests, runs, deployments, secrets and logs from a terminal, a script or an agent.
3+description: Install the g1t command line, sign in, and work with repositories, issues, pull requests, runs, workflows, deployments, secrets and logs from a terminal, a script or an agent.
44 ---
55
66 `g1t` is the command line for g1t. It does the work you would otherwise do on
248248 what you need to see why, without the rest of the log. `g1t run watch`
249249 exits `1` if the run fails.
250250
251+### Workflows
252+
253+`g1t workflow` works with the workflows in `.g1t/workflows`, as the
254+repository's **Actions** page does.
255+
256+```sh
257+g1t workflow list # those turned on; --all for every one
258+g1t workflow view ci.yml # its triggers, inputs and latest runs
259+g1t workflow view release.yml --yaml --ref v1.4.0
260+g1t workflow run release.yml -f channel=stable
261+g1t workflow disable Nightly
262+g1t workflow enable nightly.yml
263+```
264+
265+A workflow is named by its file name (`ci.yml`), its id (`wfl_…`) or its
266+name (`CI`, in any case). When more than one has that name, name it by its
267+file. Left out at a terminal, g1t asks which; in a script it is an error
268+that names what to pass.
269+
270+`g1t workflow run` runs a workflow that has `on: workflow_dispatch`, on the
271+default branch or the branch or tag `--ref` names, and prints its run's
272+address once the run is there, so `g1t run watch` can follow it. Give its
273+inputs with `-f key=value` (or `-F key=@file` to read a value from a file),
274+or as one JSON object on stdin with `--json`:
275+
276+```sh
277+echo '{"channel":"stable","dry_run":true}' | g1t workflow run release.yml --json
278+```
279+
280+At a terminal with no inputs given, g1t asks for each, offering its
281+default. Only the inputs the workflow declares are taken, as on the
282+[Actions page](/guides/actions/#runs-and-logs). `g1t workflow view --yaml`
283+prints the workflow's file as it is on the default branch, or on `--ref`.
284+Turning a workflow off keeps its file: nothing starts it until it is
285+turned on again, and a workflow the workspace requires stays on.
286+
251287 ### Deployments, logs and secrets
252288
253289 ```sh
402438 ## Scripting with JSON
403439
404440 Every command takes `--json`. Alone, it prints every field the API returns;
405−with a comma-separated list, only those:
441+with a comma-separated list, only those (`g1t workflow run` is the one
442+exception: there, `--json` alone reads the inputs from stdin):
406443
407444 ```sh
408445 g1t pr list --json number,title,check_status
504541 - Open a pull request: `g1t pr create --fill --issue <n>`
505542 - Wait for checks: `g1t pr checks --watch --fail-fast` (exit 0 passed, 1 failed)
506543 - See why a run failed: `g1t run logs --failed`
544+- Run a workflow by hand: `g1t workflow run <file> -f key=value`
507545 - Anything else: `g1t api --list <word>`, then `g1t api <operation>`
508546 ```
509547
+91−0
619619
620620 Calls [`cancel_workflow_run`](/reference/api/actions/cancel-workflow-run/).
621621
622+## g1t workflow
623+
624+Workflows in .g1t/workflows: list, view, run, enable, disable.
625+
626+### g1t workflow list
627+
628+List the workflows in .g1t/workflows, with whether each is on.
629+
630+```text
631+g1t workflow list [OPTIONS]
632+```
633+
634+| Argument or flag | |
635+| --- | --- |
636+| `-a, --all` | Include the workflows that are turned off. |
637+| `-L, --limit <LIMIT>` | Default: `50`. |
638+
639+Calls [`list_workflows`](/reference/api/actions/list-workflows/).
640+
641+### g1t workflow view
642+
643+Show a workflow and its latest runs; --yaml prints its file.
644+
645+```text
646+g1t workflow view [OPTIONS] [WORKFLOW]
647+```
648+
649+| Argument or flag | |
650+| --- | --- |
651+| `[WORKFLOW]` | Its file name (ci.yml), id (wfl_…) or name; asked for at a terminal when left out. |
652+| `-y, --yaml` | Print the workflow's file. |
653+| `-g, --ref <REF>` | The branch or tag to read the file on, with --yaml; the default branch when left out. |
654+| `-w, --web` | Open it in the browser. |
655+
656+Calls [`list_workflows`](/reference/api/actions/list-workflows/), [`get_workflow`](/reference/api/actions/get-workflow/), [`list_workflow_runs`](/reference/api/actions/list-workflow-runs/).
657+
658+### g1t workflow run
659+
660+Run a workflow that has `on: workflow_dispatch`, and print its run's address.
661+
662+```text
663+g1t workflow run [OPTIONS] [WORKFLOW]
664+```
665+
666+| Argument or flag | |
667+| --- | --- |
668+| `[WORKFLOW]` | Its file name (ci.yml), id (wfl_…) or name; asked for at a terminal when left out. |
669+| `-g, --ref <REF>` | The branch or tag to run it on; the default branch when left out. |
670+| `-f, --raw-field <KEY=VALUE>` | An input, key=value; repeat for more. |
671+| `-F, --field <KEY=VALUE>` | An input, key=value, where @FILE reads the value from a file (@- from stdin). |
672+
673+```text
674+Inputs are given with -f (or -F, where @FILE reads a file), or as a JSON object on
675+stdin with --json. At a terminal, with none given, g1t asks for each input.
676+
677+Examples:
678+ g1t workflow run release.yml
679+ g1t workflow run release.yml --ref v1.4.0 -f channel=stable -f dry_run=true
680+ echo '{"channel":"stable"}' | g1t workflow run Release --json
681+```
682+
683+Calls [`list_workflows`](/reference/api/actions/list-workflows/), [`dispatch_workflow`](/reference/api/actions/dispatch-workflow/), [`list_workflow_runs`](/reference/api/actions/list-workflow-runs/).
684+
685+### g1t workflow enable
686+
687+Turn a workflow on again.
688+
689+```text
690+g1t workflow enable [OPTIONS] [WORKFLOW]
691+```
692+
693+| Argument or flag | |
694+| --- | --- |
695+| `[WORKFLOW]` | Its file name (ci.yml), id (wfl_…) or name; asked for at a terminal when left out. |
696+
697+Calls [`list_workflows`](/reference/api/actions/list-workflows/), [`enable_workflow`](/reference/api/actions/enable-workflow/).
698+
699+### g1t workflow disable
700+
701+Turn a workflow off: its file stays, and nothing starts it until it is turned on.
702+
703+```text
704+g1t workflow disable [OPTIONS] [WORKFLOW]
705+```
706+
707+| Argument or flag | |
708+| --- | --- |
709+| `[WORKFLOW]` | Its file name (ci.yml), id (wfl_…) or name; asked for at a terminal when left out. |
710+
711+Calls [`list_workflows`](/reference/api/actions/list-workflows/), [`disable_workflow`](/reference/api/actions/disable-workflow/).
712+
622713 ## g1t secret
623714
624715 Secrets for workflows and deployments, a repository's or a workspace's.
+1−0
418418 | Action | What it does | Required | Scope |
419419 | --- | --- | --- | --- |
420420 | [`list`](/reference/api/actions/list-workflows/) | The workflows, with their events, state, problems, notes on what runs differently, manual-run inputs and last run. | `repo` | `workflows:read` |
421+| [`get`](/reference/api/actions/get-workflow/) | One workflow by its id, file name, path or name, as `list` gives it, with `source`, its file on `ref` (the default branch unless given). | `repo`, `workflow` | `workflows:read` |
421422 | [`list_runs`](/reference/api/actions/list-runs-of-workflow/) | Runs, newest first; filter by `workflow`, `branch`, `event`, `pull` or `sha`. | `repo` | `workflows:read` |
422423 | [`get_run`](/reference/api/actions/get-workflow-run/) | A run with its jobs, their steps and annotations, and its `attempts`; `attempt` reads an earlier attempt, with the jobs it had then. | `repo`, `id` | `workflows:read` |
423424 | [`job_logs`](/reference/api/actions/get-job-logs/) | A job's log after `after`; `done` says if more will come. | `repo`, `job` | `workflows:read` |
+0−0

Binary or large file; its contents are not shown.

+25−0
629629 pub viewer: Viewer,
630630 }
631631
632+/// `workflow`: one workflow, named by its id (`wfl_…`), its file name
633+/// (`ci.yml`), its path or its name, with its file as of `ref` (the
634+/// default branch when absent). Returns `Outcome<WorkflowDetail>`.
635+#[derive(Debug, Serialize, Deserialize)]
636+pub struct WorkflowArgs {
637+ pub repo: RepoPath,
638+ pub viewer: Viewer,
639+ pub workflow: String,
640+ #[serde(default, rename = "ref")]
641+ pub git_ref: Option<String>,
642+}
643+
644+/// A workflow with its file.
645+#[derive(Clone, Debug, Serialize, Deserialize)]
646+#[serde(rename_all = "camelCase")]
647+pub struct WorkflowDetail {
648+ #[serde(flatten)]
649+ pub workflow: Workflow,
650+ /// The branch or tag the file was read from.
651+ #[serde(rename = "ref")]
652+ pub git_ref: String,
653+ /// The file, as written on `ref`.
654+ pub source: String,
655+}
656+
632657 /// `runs`: newest first. Returns `Outcome<Vec<WorkflowRun>>`.
633658 #[derive(Debug, Serialize, Deserialize)]
634659 pub struct RunsArgs {
+1−0
284284 "get_context",
285285 "search",
286286 "list_workflows",
287+ "get_workflow",
287288 "list_workflow_runs",
288289 "get_workflow_run",
289290 "get_job_logs",
+1−0
11381138 ("record_session_entries", Scope::PullRequestsWrite),
11391139 // Workflows.
11401140 ("list_workflows", Scope::WorkflowsRead),
1141+ ("get_workflow", Scope::WorkflowsRead),
11411142 ("list_workflow_runs", Scope::WorkflowsRead),
11421143 ("get_workflow_run", Scope::WorkflowsRead),
11431144 ("get_job_logs", Scope::WorkflowsRead),
+73−0
1212 g1t pr create --fill
1313 g1t pr checks --watch --fail-fast
1414 g1t run logs --failed
15+ g1t workflow run release.yml -f channel=stable
1516 g1t api list_issues --jq '.[].title'
1617
1718 Environment:
9192 /// Workflow runs: list, view, watch, logs, rerun, cancel.
9293 #[command(subcommand)]
9394 Run(RunCommand),
95+ /// Workflows in .g1t/workflows: list, view, run, enable, disable.
96+ #[command(subcommand)]
97+ Workflow(WorkflowCommand),
9498 /// Secrets for workflows and deployments, a repository's or a workspace's.
9599 #[command(subcommand)]
96100 Secret(SecretCommand),
679683 pub debug: bool,
680684 }
681685
686+// --- workflow ---------------------------------------------------------
687+
688+#[derive(Debug, Subcommand)]
689+pub enum WorkflowCommand {
690+ /// List the workflows in .g1t/workflows, with whether each is on.
691+ List(WorkflowListArgs),
692+ /// Show a workflow and its latest runs; --yaml prints its file.
693+ View(WorkflowViewArgs),
694+ /// Run a workflow that has `on: workflow_dispatch`, and print its run's address.
695+ #[command(after_help = "\
696+Inputs are given with -f (or -F, where @FILE reads a file), or as a JSON object on
697+stdin with --json. At a terminal, with none given, g1t asks for each input.
698+
699+Examples:
700+ g1t workflow run release.yml
701+ g1t workflow run release.yml --ref v1.4.0 -f channel=stable -f dry_run=true
702+ echo '{\"channel\":\"stable\"}' | g1t workflow run Release --json")]
703+ Run(WorkflowRunArgs),
704+ /// Turn a workflow on again.
705+ Enable(WorkflowSelect),
706+ /// Turn a workflow off: its file stays, and nothing starts it until it is turned on.
707+ Disable(WorkflowSelect),
708+}
709+
710+#[derive(Debug, Args)]
711+pub struct WorkflowSelect {
712+ /// Its file name (ci.yml), id (wfl_…) or name; asked for at a terminal when left out.
713+ pub workflow: Option<String>,
714+}
715+
716+#[derive(Debug, Args)]
717+pub struct WorkflowListArgs {
718+ /// Include the workflows that are turned off.
719+ #[arg(short, long)]
720+ pub all: bool,
721+ #[arg(short = 'L', long, default_value_t = 50)]
722+ pub limit: usize,
723+}
724+
725+#[derive(Debug, Args)]
726+pub struct WorkflowViewArgs {
727+ /// Its file name (ci.yml), id (wfl_…) or name; asked for at a terminal when left out.
728+ pub workflow: Option<String>,
729+ /// Print the workflow's file.
730+ #[arg(short, long)]
731+ pub yaml: bool,
732+ /// The branch or tag to read the file on, with --yaml; the default branch when left out.
733+ #[arg(short, long = "ref", value_name = "REF", requires = "yaml")]
734+ pub git_ref: Option<String>,
735+ /// Open it in the browser.
736+ #[arg(short, long, conflicts_with = "yaml")]
737+ pub web: bool,
738+}
739+
740+#[derive(Debug, Args)]
741+pub struct WorkflowRunArgs {
742+ /// Its file name (ci.yml), id (wfl_…) or name; asked for at a terminal when left out.
743+ pub workflow: Option<String>,
744+ /// The branch or tag to run it on; the default branch when left out.
745+ #[arg(short, long = "ref", value_name = "REF")]
746+ pub git_ref: Option<String>,
747+ /// An input, key=value; repeat for more.
748+ #[arg(short = 'f', long = "raw-field", value_name = "KEY=VALUE")]
749+ pub raw_field: Vec<String>,
750+ /// An input, key=value, where @FILE reads the value from a file (@- from stdin).
751+ #[arg(short = 'F', long = "field", value_name = "KEY=VALUE")]
752+ pub field: Vec<String>,
753+}
754+
682755 // --- secret -----------------------------------------------------------
683756
684757 #[derive(Debug, Subcommand)]
+2−0
1616 pub mod status;
1717 pub mod why;
1818 pub mod work;
19+pub mod workflow;
1920
2021 use clap::CommandFactory;
2122
4041 Command::Issue(command) => issue::run(&Ctx::new(cli.global)?, command),
4142 Command::Pr(command) => pr::run(&Ctx::new(cli.global)?, command),
4243 Command::Run(command) => run::run(&Ctx::new(cli.global)?, command),
44+ Command::Workflow(command) => workflow::run(&Ctx::new(cli.global)?, command),
4345 Command::Secret(command) => secret::run(&Ctx::new(cli.global)?, command),
4446 Command::Cache(command) => cache::run(&Ctx::new(cli.global)?, command),
4547 Command::Deploy(command) => deploy::run(&Ctx::new(cli.global)?, command),
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…

Comments

Sign in to comment.