---
title: PushOptions
description: The options of `push()`.
---

# `PushOptions`

Type, in `@jr2/orchestrator/src/sandbox-effect.ts`. The signature of an export, or a type that it names, names this type. The [Authoring surface](../authoring-surface.md) page lists each export. This type is not an export of `@jr2/orchestrator`, so a workflow module does not import it by name.

```ts
type PushOptions = {
  pin?: boolean;
  sign?: boolean;
  squash?: boolean;
  force?: boolean;
  slot?: string;
  timeout?: Duration;
};
```

The options of `push()`.

**Fields**

- `pin` (optional): `boolean`

  `true`: the input of the Effect names the commit to push (`{ sha }`, a full commit id, for
  example one that a Gate approved). Default: the tip of the Agent's branch when the Effect
  starts. When the Agent removed that commit from its branch, the remote refuses the push. jr2
  never pushes another commit in its place.

  When it starts, it refuses a `sha` that is not a full commit id: `push({ pin: true }): its
  input's sha is not a full commit id (got <sha>)`.
- `sign` (optional): `boolean`

  `true`: push signed copies of the commits. The `sign` field of the `git.credentials` entry that
  the Binding matches names the key. Default `false`.

  At `jr2 up`, it refuses an entry with no `sign` field: `<push> signed, and git.credentials
  entry "<match>" holds no sign field — add sign: { sshKey: "<a Secret with identity>", name:
  "<committer name>", email: "<committer email>" } to it; the email must belong to the forge
  account that holds the key (ADR-0051, ADR-0067)`. `<push>` names the push: `workflow
  "<workflow>": push "<slot>" pushes Repo Slot "<name>" (<url>)`.
- `squash` (optional): `boolean`

  `true`: push one commit that holds all the changes. The input of the Effect gives its message
  (`{ message }`). Signed, its committer is the signer. Unsigned, it is the `committer` of the
  `git.credentials` entry that the Binding matches. Default `false`.

  When it starts, it refuses an input with no message: `push({ squash: true }): its input
  carries no message`.

  At `jr2 up`, it refuses an unsigned squash whose entry has no `sign` and no `committer`:
  `<push> squashed without sign, and git.credentials entry "<match>" holds neither sign nor
  committer — the squashed commit is new and needs a committer; add committer: { name:
  "<committer name>", email: "<committer email>" } to it, or sign the push — push({ squash:
  true, sign: true }) — and add sign: { sshKey: "<a Secret with identity>", name: "<committer
  name>", email: "<committer email>" } to it (ADR-0051, ADR-0067)`.
- `force` (optional): `boolean`

  `true`: replace what the remote branch holds. Default `false`.
- `slot` (optional): `string`

  The Repo Slot to push. Write it only when the Workspace has more than one.

  When it starts, it refuses:
  - no `slot` under a Workspace with more than one Repo Slot: `push "<slot>" runs under a
    Workspace carrying more than one Repo Slot (<slots>) — say which: { slot: "<slot>" }
    (ADR-0051)`
  - a `slot` that the Workspace does not have: `push "<slot>" names Repo Slot "<name>", which
    its Workspace does not carry (<slots>)`
  - a Workspace with no Repo Slot: `push "<slot>" runs under a Workspace with no Repo Slot: a
    push publishes a Repo Slot's branch, and there is none — declare one: repos: { app: "<url>" }
    (ADR-0051)`. `jr2 up` refuses it first, with the same reason.
- `timeout` (optional): [`Duration`](type-duration.md)

  How long jr2 waits for the push: a number and a unit, such as `"90s"` or `"5m"`. Default
  `"5m"`. With no answer in that time, the output is `unknown`. It refuses a value that is not a
  positive duration: `timeout "<timeout>" is not a positive duration (like "30s", "5m")`.
