Guides

Openship Actions

Run GitHub-compatible workflows on connected servers and temporary Cloud runners.

Actions runs repository CI and standalone automation on Openship's authorized destinations. Workflows can be linked to projects or run independently. Jobs can schedule an application command or invoke a saved workflow, with the same Actions execution, topology and logs.

Workflow sources

Select a repository and Openship discovers its workflows. The file's location selects its integration automatically; the editor, destinations, capacity limits and run history stay together.

  • .github/workflows/: GitHub coordinates the workflow and its Checks, secrets, environments, artifacts and caches. Official runners on your selected Openship destinations execute jobs routed to them. This supports reusable workflows, releases, tags and protected environments.
  • .openship/workflows/ or Standalone: Openship schedules the YAML and runs jobs with act, using its scoped credentials and configured storage. The compatibility limits below apply to these independent workflows.

Run only in Openship

Store the workflow in .openship/workflows/ci.yml. GitHub ignores this directory: using GitHub's YAML syntax does not start GitHub Actions. Openship discovers the file, schedules its declared triggers and executes jobs on your allowed runners. This also works when GitHub Actions is disabled for the repository.

  1. Add the file to the repository. When moving CI from GitHub, move the file out of .github/workflows/; leaving a copy there keeps its GitHub triggers active.
  2. Open the project's Actions tab, select the repository and import the file.
  3. Choose the runners, access policy and notifications, then save.
  4. Run it manually or push a commit matching its on: push rules. Automatic GitHub events require a connected App subscribed to those events and a reachable webhook.

For example, this workflow checks out a private repository and runs its Node tests on an allowed Linux runner with Git and Node available:

.openship/workflows/ci.yml
name: CI
on:
  push:
    branches: [main]
  workflow_dispatch:
permissions:
  contents: read
jobs:
  test:
    runs-on: [self-hosted, openship, linux]
    steps:
      - uses: actions/checkout@v4
      - run: node --test

Private checkout uses a repository-scoped App token. Publishing results needs the App's Checks: write permission. An Openship Check on a commit is a status report; it does not create a GitHub Actions run. Follow execution and live logs in Openship. The independent-workflow compatibility limits below still apply.

Use GitHub-coordinated workflows

Files in .github/workflows/ require runner-management access: a GitHub App with Actions: write and Administration: write, or a suitable repository token. Existing App installations may need to approve these permissions. Editing workflow files also needs Contents: write and Workflows: write; new Openship App manifests request them for the editor. Configure secrets and variables in GitHub's repository or organization settings.

To route jobs to Openship, use explicit labels:

runs-on: [self-hosted, openship, linux, x64]

For a connected Mac, use macos and its actual CPU architecture. A plain ubuntu-latest job remains on GitHub-hosted runners. Add a Cloud size label such as openship-linux-2 when selecting a specific allowed profile.

A GitHub runner registration belongs to the repository and may receive any matching job, including reusable-workflow jobs. Openship checks the actual assigned workflow, requester and approval before starting workflow code. Configure that policy in the Access step; a matching label alone does not grant permission.

Add a runner

Open Actions → Runners → Add runner and choose a destination:

  • Existing server: select a connected or managed application server. Set per-job CPU, memory and parallel limits to leave capacity for its applications. The server keeps its existing billing.
  • Dedicated server: create a managed server through the shared server and plan dialog, then configure it as a runner. Its normal server subscription applies.
  • Temporary Cloud runners: choose a disposable VM profile using your prepaid Actions balance. Each executed job gets a VM, which is removed after cleanup.

Openship probes the selected server's OS, architecture, Git, Node and Docker capabilities before enabling a runtime.

  • Linux containers: use a runner image with the tools your workflow needs. Docker and service-container actions require Docker on the destination.
  • Native Linux: use the server's installed toolchain with Git and Node available.
  • Native macOS: use a connected Mac with Git and Node installed. Native mode is selected by default, even when the Mac also has Docker. Jobs execute as the connected server user and share that user's filesystem and installed tools.
  • Temporary Cloud runners: each job receives a disposable Linux VM. Its funding is separate from managed application-server subscriptions.

The runner picker shows its execution OS, Docker/native mode and verified CPU architectures. Expand Environment & labels to see the host version, default image, per-job limits and routing labels. For example, an Ubuntu 24.04 host can use an Ubuntu 22.04 default container image; these are separate environments.

New connected runners use their verified OS and architecture labels. The Ubuntu image preset does not add ubuntu-latest or a version alias. Existing saved labels remain intact. Add a custom routing label only when your workflow needs it; a label does not select a different image or install tools.

Only run trusted code on persistent destinations. Enabling a native runner gives its workflows the same host access as the connected user. Runner labels select compatible capabilities; adding macos to a Linux runner does not make it a Mac.

The runner image is a default. Each job can use its own compatible Linux image with jobs.<job>.container, including Debian, Alpine and language images. The image must provide the shell and tools used by its steps; a minimal image does not include the full GitHub-hosted toolchain. Container image options and registry credentials remain available in YAML.

For container runners, Enable CPU emulation installs the missing QEMU/binfmt support on the selected Docker host and verifies it by executing a foreign binary. It requires server administration access. Existing working emulators are reused. Normal capability checks do not install packages or register emulators. Use the standard x64 or arm64 runner label to select a CPU; use a matrix for both:

jobs:
  test:
    strategy:
      matrix:
        arch: [x64, arm64]
    runs-on: [self-hosted, openship, linux, "${{ matrix.arch }}"]
    container: alpine:3.22
    steps:
      - shell: sh
        run: uname -m

The selected image needs a build for that architecture. QEMU can be slower than native execution. runner.arch and RUNNER_ARCH describe the selected execution architecture; native macOS jobs still need a real Mac.

Allow Docker access enables Docker build actions on a connected container runner; enable it only for trusted workflows because it grants access to that server's Docker daemon. Cloud job containers use the Docker daemon of their own private disposable VM. They receive no provider credentials or access to other customers' machines.

Connect a workflow

Open Actions → Add workflow, Project → Actions, or the Actions section in the deployment wizard. These entry points share the same setup:

  1. Select a repository and branch. Openship discovers files in .github/workflows/ and .openship/workflows/ and previews their job dependencies as a topology. Check several files or choose Select all to add them together. Select a filename to preview it; each file keeps its own draft and undo history.
  2. The canvas stays visible while you edit. Select a job to open its settings in the right panel. Expand its canvas node to reveal a grid of step cards connected by execution-order arrows; selecting a step opens its editor. List edits those same steps inline on the left, without duplicating them in the right panel. Jobs and steps expand independently, and open steps stay open when switching views. Connect jobs to set dependencies and select a connection to remove it. List and YAML show the same draft; undo and redo work across views. Job YAML exposes matrix, services, conditions, permissions and step inputs. Dependency cycles and deletion of referenced job outputs are rejected.
  3. Use Run settings on the right to choose the required runners and configure triggers. If no runner exists, the selector opens runner setup in a modal; saving selects the new runner without leaving your draft. The current project is linked automatically. The generic editor keeps extra project links under a disclosure. Independent workflows also configure variables, secrets and artifact storage here; GitHub workflows use their repository settings. Runner destinations, enabled state and project links apply to the selected files. Trigger edits apply to the file being previewed.
  4. In Access, choose who can run and whether each run needs approval. Defaults allow only your connected account, require approval for each run and block forks. Choose specific GitHub users or repository collaborators with write access to extend access. These settings apply to the selected files.
  5. In Checks, review the connected GitHub account and the selected repository's access. Connect GitHub or Review access opens setup without leaving your draft; unavailable checks can be retried. GitHub workflows retain their original Checks. Independent repository workflows need a GitHub App with Checks: write. For notifications, choose Add channel, enter its destination and select Send test & use. Failed verification stays retryable in the same dialog. Select failures, successes or cancellations; notifications remain optional. Choose required workflows in the project's Deployment automation tab.
  6. Save the workflow. Canvas and trigger edits preserve unrelated YAML and expressions. Before writing back to GitHub, review the changes and choose Commit and save. .openship/workflows also offers Save Openship copy. .github/workflows always runs committed YAML. A changed file on GitHub rejects the commit instead of overwriting someone else's changes.

GitHub workflow management uses the instance's existing credential resolver: an authorized local CLI login, personal token, or repository-scoped GitHub App (including an App connected through Openship Cloud). A detected CLI login can read repository information before you authorize it for management. Choose Review access → Change method → Use gh CLI to select it explicitly. Repository Actions and runner-management permissions still apply; signing into GitHub alone does not grant them. Cloud uses the connected user's credentials or App installation and never the Cloud host's CLI login. Independent Checks use a GitHub App with Checks write access. Actions currently supports github.com, not GitHub Enterprise destinations.

All selected files are validated before their workflow records and project links are saved in one transaction. Retrying an import reuses existing records, retains their settings and adds any new project links; it does not duplicate workflows or start a run. Edit an already connected workflow from its Actions page to change its saved configuration. Reviewed repository commits can trigger the repository's normal automation, and are separate from the database transaction.

Access and approvals

Access policies apply on both connected servers and Cloud destinations. Only my account uses your connected GitHub identity for repository workflows and your Openship identity for standalone workflows. Selected GitHub users are verified by account ID; the original requester and anyone retrying a run must both be eligible.

With Approve each run, an Actions administrator with access to its destinations reviews the commit, attempt and runners before any runner is allocated. Changing the policy, destinations or execution settings requires a new review. A retry does not inherit the previous attempt's approval. Open the run's Approvals tab to review it; a yellow icon marks pending or blocked access. The tab explains blocked access and links back to workflow settings without covering the job list or logs.

Automatically allow eligible users skips Openship's review for trusted runs. GitHub's fork and protected-environment approvals still apply; the editor links to repository settings. GitHub does not require approval for every collaborator push by default. Choose per-run approval when you need that control. Eligible fork runs always need Openship approval and a disposable Cloud runner.

Existing independent workflows keep their previous behavior until their access settings are saved. Existing GitHub workflows without a policy require review before Openship starts new runners. The official runner adapter verifies the actual assignment through GitHub's local IPC protocol and fails closed if that protocol becomes incompatible; it does not fall back to unchecked execution.

Workflow notifications use the existing notification queue, alongside account-wide Actions subscriptions. A channel selected by both rules gets one queued notification per run. Jobs that invoke a workflow share that identity. Failed enqueues are retried before completion is settled, and delivery rechecks channel verification and resource access. Notification choices are captured when the run is created; importing old GitHub history does not send a backlog of alerts. No workflow commands, secrets or raw logs are included in these notifications.

Choose Standalone for YAML without a repository. It supports manual runs, schedules and authenticated webhooks without GitHub credentials. actions/checkout in a standalone workflow needs an explicit with.repository.

Repository updates for .openship/workflows controls which definition future runs use. Files in .github/workflows always use the definition from GitHub for that run:

  • Automatic: use the workflow from the run's repository commit. Changes in Git apply automatically.
  • Review first: keep the YAML saved in Openship. Check repository loads the latest file without replacing your saved definition or edited draft. Review the differences, choose Use repository version, then save to approve it. Until then, runs continue using the previously saved YAML.

Saving an Openship copy selects Review first. Changing the definition affects future runs; existing runs retain their immutable snapshots.

name: CI
on:
  push:
    branches: [main]
  workflow_dispatch:
permissions:
  contents: read
jobs:
  build:
    runs-on: [self-hosted, openship, linux]
    strategy:
      matrix:
        node: [20, 22]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
      - run: npm ci
      - run: npm test
  complete:
    needs: build
    runs-on: [self-hosted, openship, linux]
    steps:
      - run: echo "All matrix jobs passed"

Every run records the resolved commit and workflow definition. Rerunning creates a new attempt of that recorded revision. A controller restart resumes inspection of the same worker; it does not replay a job whose start was already accepted.

The run page opens with a collapsible job-and-step list on the left and logs on the right. Select a job for all its output, or a step for its recorded output. Jobs expand independently. Switching to Topology keeps the same selection and logs; use Expand all, Collapse all, zoom, fit or Arrange workflow to inspect the connected steps. Independent jobs wrap across the graph rather than forming one long column. A single job shows its step nodes immediately. The selected job, step and view are preserved in the URL when you refresh or share the page. Queued and waiting jobs keep their own status labels and use a yellow loading indicator. Opening Approvals preserves the current job, step and log cursor.

Independent logs resume from their persisted cursor. For GitHub workflows, step state is synchronized from GitHub, live logs open in GitHub, and completed logs and artifacts are available in Openship. GitHub supplies a complete job log, so selecting a step keeps that full output visible with a scope label. GitHub owns the Check IDs and conclusions; Openship does not publish duplicate Checks.

Triggers and Jobs

When to run edits the workflow's own on rules. It supports manual inputs, push and pull-request branch/path filters, UTC Cron schedules and authenticated webhooks. Expand a trigger to configure it. Branches and paths use removable patterns: type a pattern and press Enter or + to add it. Choose Only matching or Except matching; Openship preserves commas inside glob patterns. Paths & more filters includes tags and pull-request event types. Each Cron schedule has its own UTC input. Other events, including workflow_call, remain visible and open the YAML editor without changing their definitions.

Manual & Jobs enables workflow_dispatch. Add string, number, boolean or choice inputs with defaults and required values. The manual-run form and Jobs → Run workflow use those same declared inputs. Jobs can run a workflow on a Cron schedule, once, after another job succeeds or on a supported platform event. Allowed runners and secrets remain configured on the workflow. Job history opens the original Actions execution rather than a second copy of its logs or status.

For an independent workflow's authenticated webhook, enable repository_dispatch and optionally restrict event types. The workflow details show its dispatch endpoint. Call it with an Openship API token authorized to run that workflow:

POST /api/actions/workflows/WORKFLOW_ID/dispatch
Authorization: Bearer YOUR_OPENSHIP_TOKEN
Content-Type: application/json

{
  "eventType": "release",
  "clientPayload": { "version": "1.2.3" },
  "idempotencyKey": "release-1.2.3"
}

The workflow receives these values in github.event.action and github.event.client_payload. Keep the token in the caller's secret store and reuse the same idempotency key when retrying one delivery. This is Openship's authenticated dispatch API; it does not subscribe to GitHub App repository_dispatch deliveries. The caller must be able to reach the instance. For .github/workflows, send repository_dispatch events to GitHub's repository dispatch API instead. Openship's Run button and Jobs schedules use GitHub's workflow_dispatch endpoint.

Project deployment rules

In Project → Actions, create a workflow or open Deployment automation to link existing workflows and select:

  • Manual deployments: workflows run independently; deployment starts when requested.
  • Deploy on push: use the project's existing automatic deployment pipeline.
  • Deploy after Actions pass: require all selected workflows to pass for the exact pushed commit before entering that same deployment pipeline.

Required workflows must be enabled, belong to the project's repository and run on every push to its deployment branch. Path-filtered workflows can be linked as optional checks. Required checks need a reachable control plane and an authenticated repository push webhook. Independent Checks additionally require a connected GitHub App to publish results. GitHub-mode deployment gates wait for the original GitHub push run; they do not dispatch another run. Manual deployments remain available.

Pending requests and failed checks appear in the project's Actions tab. Retrying uses the saved commit and one deployment receipt; duplicate deliveries or a controller restart do not create another accepted deployment. Newer commits, changed rules and a new manual deployment supersede pending approvals. Pull-request runs and manual workflow runs do not approve automatic push deployments.

The deployment wizard saves its selected workflow links and rules before starting the initial deployment. If rule setup fails, it keeps the draft for retry. The initial deployment remains an explicit manual deployment; the selected automatic policy applies to subsequent pushes.

GitHub events and checks

For independent workflows, a connected GitHub App receives signed push and pull-request events and publishes Checks on the commit. Each job uses a token scoped to its repository and declared permissions. Stored personal credentials are not substituted for an unavailable App token. GitHub installation tokens normally expire after one hour; token refresh inside a running job is not currently supported.

Independent scheduled workflows run while the controller is online, at intervals of at least five minutes. Missed schedules are not replayed after downtime. For Desktop, keep it running or move the control plane to a server.

Schedules in .github/workflows are managed by GitHub. Openship must be online to provision and register its runners. Signed workflow_run/workflow_job events request a fresh API read; periodic reconciliation also recovers missed events. Event payloads alone cannot mark a run successful.

Use .openship/workflows/ when you want scheduling independent of GitHub. If a workflow script deploys the application itself, use manual project deployment mode to avoid also requesting an automatic deployment after its checks pass.

Independent fork runs require explicit approval and disposable runners. Their workflow comes from the trusted base revision, while checkout can use the pull-request merge commit. They receive no stored secrets, write credential or shared cache access. Authorization is rechecked during execution; revoking the originating user's access prevents further authorized work.

Fork approvals and protected-environment approvals for .github/workflows still follow GitHub repository policy. Openship also requires its own approval and a disposable Cloud runner for eligible fork runs. Forks never run on connected persistent servers, including Macs. pull_request_target is also treated as untrusted.

Artifacts and cache

Files in .github/workflows use GitHub's artifact/cache service, retention and storage billing. Download links are fetched with repository authorization and returned as short-lived signed links; credentials are never forwarded to the download host.

For independent workflows, select an existing backup destination for artifacts and cache. Cloud requires an S3-compatible destination; self-hosted instances can also use a local destination. Workflow code never receives the destination's storage credentials.

The API implements the protocols used by actions/upload-artifact@v4, actions/download-artifact@v4 and actions/cache@v4. One object is limited to 1 GiB, with 20 GiB of reserved and retained objects per organization. Artifact retention defaults to seven days and can be set up to 30 days. Expired objects are removed by the controller's cleanup loop.

Runners must be able to reach the instance's public API. Set OPENSHIP_ACTIONS_RUNTIME_URL when it differs from OPENSHIP_PUBLIC_URL; preserve the artifact API and /twirp proxy routes. Runtime URLs use short-lived tokens scoped to one organization, run and job.

Independent reusable workflows

Use jobs.<job>.uses to call a YAML file in .openship/workflows/ or .github/workflows/. Local calls use the caller's immutable commit. Remote calls use owner/repository/path@ref; Openship resolves the ref and saves every called source before approval. A later tag change cannot alter an approved attempt.

jobs:
  gate:
    uses: ./.openship/workflows/test.yml
    with:
      enabled: false
      version: 22
    secrets:
      registry_token: ${{ secrets.REGISTRY_TOKEN }}

The called file declares on: workflow_call, typed inputs, accepted secrets and outputs. Its jobs select their own allowed runners and appear in the same run, with logs, Checks and cancellation. Boolean and number inputs retain their types. Permissions can stay the same or narrow at each call. Secrets must be forwarded explicitly; secrets: inherit is permitted only within the same owner. Nesting is limited to 10 workflow levels, 50 called files, 2 MiB of combined source and 256 total concrete jobs. Protected environment settings remain unsupported in independent mode.

Openship OIDC

Independent jobs can request an identity with permissions: {id-token: write}. Publish the controller at a stable HTTPS origin reachable from runners and the external service. Configure that service to trust https://your-controller/api/actions/oidc as its issuer. Discovery is available at /api/actions/oidc/.well-known/openid-configuration; RSA verification keys are at /api/actions/oidc/jwks.

The job receives the standard ACTIONS_ID_TOKEN_REQUEST_URL and ACTIONS_ID_TOKEN_REQUEST_TOKEN environment variables. Actions using the standard OIDC toolkit can request a token with their required audience. Credentials such as AWS or Azure trust policies must allow this Openship issuer; GitHub-specific issuer policies do not grant access automatically.

Restrict the provider's trust to the organization, repository, ref and workflow identity. A normal repository subject is openship:organization:<org-id>:repo:<owner>/<repo>:ref:refs/heads/main. A workflow edited in Openship includes :source:override in its subject and sets openship_workflow_modified, so it cannot impersonate the repository's committed workflow. Claims also identify the run, job, destination and immutable called workflow source (job_workflow_ref, job_workflow_sha).

Tokens expire within five minutes. Issuance rechecks approval, actor access, runner access and cancellation; fork jobs receive no OIDC capability. The instance's signing key is encrypted in its database and included only in a full instance transfer, preserving its key when credentials are transferred securely. Keep the issuer address stable when moving a control plane. An archive that omits credentials retains public verification metadata but cannot issue new tokens; restore an archive containing the signing credentials to use that issuer.

Cancellation and limits

Cancel stops the remote execution and then cleans its resources. A runner remains busy until cleanup succeeds. Cloud workers also have a provider TTL as a fallback; an unreachable controller does not leave a VM running indefinitely.

Independent workflows support up to 256 concrete jobs after matrix expansion. A job defaults to a 60-minute timeout and can request up to 360 minutes. Logs are bounded at 8 MiB per job. Settled run history is retained for 30 days, with runs referenced by retained artifacts or retry attempts protected from early removal.

Independent workflows support reusable workflows and Openship-issued OIDC. Protected environments and attestations require GitHub-coordinated workflows; independent mode rejects those features before dispatch. Openship-managed destinations currently support Linux and macOS; Windows and GitHub Enterprise Server are not available. Official runner registrations execute one job and expire after six hours; idle registrations are removed after ten minutes. Choose a runner image with the official runner's dependencies, or use the Ubuntu preset.

GitHub dispatch and rerun POSTs have durable command receipts. If GitHub accepts a request but its response is lost, Openship does not send the POST twice. Refresh Runs or open GitHub before deliberately starting another run.

Cloud Actions funding

Actions → Budget provides a separate prepaid balance for temporary VMs and transfer. Add $5, $20, $50 or $100, complete the hosted payment, and return to see its verified status. Runner setup retries automatically if the provider is unavailable; it does not buy another deposit. Once ready, choose the Cloud runners in your workflow's allowed destinations.

RunnerRAMTemporary disk
2 vCPU4 GiB40 GiB
4 vCPU8 GiB80 GiB
8 vCPU16 GiB160 GiB

All sizes share two concurrent Cloud jobs per organization. You can select a size with runs-on: [self-hosted, openship, linux, openship-linux-2], openship-linux-4 or openship-linux-8, provided that profile is allowed for the workflow.

The page shows live provider rates and estimated VM minutes for your deposit. Estimates assume full CPU and memory use, before transfer or disk I/O. Actual charges follow measured CPU time, memory and combined uploads/downloads. VM preparation, failed steps and cleanup can consume credits; queued jobs use no VM. This is prepaid usage, not a fixed number of execution minutes or a subscription.

Your displayed balance comes from Oblien. Recent usage may appear with a delay. Workers stop when the provider marks the balance exhausted. Add funds and rerun the workflow to try again; an interrupted attempt is not silently restarted. Independent artifacts and caches use your configured storage destination; GitHub mode uses GitHub storage. Connected servers run workflows without spending this Cloud Actions balance.

On this page