Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 0 additions & 2 deletions .github/workflows/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ jobs:
owner: codex-
workflow: dispatch.yml
workflow_inputs: '{"cake":"delicious"}'
workflow_timeout_seconds: 30
workflow_job_steps_retry_seconds: 10
- name: Evaluate that the Run ID output has been set
run: |
if [ "${{ steps.return_dispatch.outputs.run_id }}" == "" ]; then
Expand Down
4 changes: 0 additions & 4 deletions .github/workflows/dispatch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@ name: action-test
on:
workflow_dispatch:
inputs:
distinct_id:
required: true
cake: # Test for input passthrough.
required: true

jobs:
test:
runs-on: ubuntu-latest
steps:
- name: echo distinct ID ${{ github.event.inputs.distinct_id }}
run: echo ${{ github.event.inputs.distinct_id }}
- name: echo input passthrough
run: echo ${{ github.event.inputs.cake }}
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
- v1.*
- v2.*
- v3.*
- v4.*

permissions:
contents: write
Expand Down
111 changes: 17 additions & 94 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
# GitHub Action: return-dispatch

[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/codex-/return-dispatch/test.yml?style=flat-square)](https://github.com/Codex-/return-dispatch/actions/workflows/test.yml) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) [![codecov](https://img.shields.io/codecov/c/github/Codex-/return-dispatch?style=flat-square)](https://codecov.io/gh/Codex-/return-dispatch) [![GitHub Marketplace](https://img.shields.io/badge/Marketplace-return–dispatch-blue.svg?colorA=24292e&colorB=0366d6&style=flat-square&longCache=true&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAM6wAADOsB5dZE0gAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAERSURBVCiRhZG/SsMxFEZPfsVJ61jbxaF0cRQRcRJ9hlYn30IHN/+9iquDCOIsblIrOjqKgy5aKoJQj4O3EEtbPwhJbr6Te28CmdSKeqzeqr0YbfVIrTBKakvtOl5dtTkK+v4HfA9PEyBFCY9AGVgCBLaBp1jPAyfAJ/AAdIEG0dNAiyP7+K1qIfMdonZic6+WJoBJvQlvuwDqcXadUuqPA1NKAlexbRTAIMvMOCjTbMwl1LtI/6KWJ5Q6rT6Ht1MA58AX8Apcqqt5r2qhrgAXQC3CZ6i1+KMd9TRu3MvA3aH/fFPnBodb6oe6HM8+lYHrGdRXW8M9bMZtPXUji69lmf5Cmamq7quNLFZXD9Rq7v0Bpc1o/tp0fisAAAAASUVORK5CYII=)](https://github.com/marketplace/actions/return-dispatch)
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/codex-/return-dispatch/test.yml?style=flat-square)](https://github.com/Codex-/return-dispatch/actions/workflows/test.yml) [![codecov](https://img.shields.io/codecov/c/github/Codex-/return-dispatch?style=flat-square)](https://codecov.io/gh/Codex-/return-dispatch) [![GitHub Marketplace](https://img.shields.io/badge/Marketplace-return–dispatch-blue.svg?colorA=24292e&colorB=0366d6&style=flat-square&longCache=true&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAM6wAADOsB5dZE0gAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAERSURBVCiRhZG/SsMxFEZPfsVJ61jbxaF0cRQRcRJ9hlYn30IHN/+9iquDCOIsblIrOjqKgy5aKoJQj4O3EEtbPwhJbr6Te28CmdSKeqzeqr0YbfVIrTBKakvtOl5dtTkK+v4HfA9PEyBFCY9AGVgCBLaBp1jPAyfAJ/AAdIEG0dNAiyP7+K1qIfMdonZic6+WJoBJvQlvuwDqcXadUuqPA1NKAlexbRTAIMvMOCjTbMwl1LtI/6KWJ5Q6rT6Ht1MA58AX8Apcqqt5r2qhrgAXQC3CZ6i1+KMd9TRu3MvA3aH/fFPnBodb6oe6HM8+lYHrGdRXW8M9bMZtPXUji69lmf5Cmamq7quNLFZXD9Rq7v0Bpc1o/tp0fisAAAAASUVORK5CYII=)](https://github.com/marketplace/actions/return-dispatch)

Dispatch an action to a foreign repository and output the newly created run ID.

This Action exists as a workaround for the issue where dispatching an action to foreign repository does not return any kind of identifier.

The returned run ID can be used to await the completion of the remote run using [`await-remote-run`](https://github.com/Codex-/await-remote-run).

## Usage

Ensure you have configured your remote action correctly, see below for an example.

### Dispatching Repository Action
The dispatched workflow needs no special setup. It only has to accept the `workflow_dispatch`
event and declare any inputs you pass via `workflow_inputs`.

```yaml
steps:
Expand All @@ -26,12 +23,6 @@ steps:
owner: repository-owner
workflow: automation-test.yml
workflow_inputs: '{ "some_input": "value" }' # Optional
workflow_timeout_seconds: 120 # Default: 300
workflow_job_steps_retry_seconds:
# Lineal backoff retry attempts are made where the attempt count is
# the magnitude and the scaling value is `workflow_job_steps_retry_seconds`
10 # Default: 5
distinct_id: someDistinctId # Optional

- name: Use the output run ID and URL
run: |
Expand All @@ -47,101 +38,33 @@ steps:
run_id: ${{ steps.return_dispatch.outputs.run_id }}
```

### Receiving Repository Action

In the earliest possible stage for the Action, add the input into the name.

As every step needs a `uses` or `run`, simply `echo` the ID or similar to satisfy this requirement.

```yaml
name: action-test
on:
workflow_dispatch:
inputs:
distinct_id:

jobs:
test:
runs-on: ubuntu-latest
steps:
- name: echo distinct ID ${{ inputs.distinct_id }}
run: echo "${DISTINCT_ID}"
env:
DISTINCT_ID: ${{ inputs.distinct_id }}
```

## Token

To be able to use dispatch we need to use a token which has `repo` permissions. `GITHUB_TOKEN` currently does not allow adding permissions for `repo` level permissions currently so a Personal Access Token (PAT) must be used.
`GITHUB_TOKEN` can only access the repository containing the workflow, so dispatching
to another repository requires a Personal Access Token (PAT). Dispatching within the
same repository works with `GITHUB_TOKEN`, provided it is granted `actions: write`.

### Permissions Required

The permissions required for this action to function correctly are:
One of the following, depending on the token type:

- `repo` scope
- You may get away with simply having `repo:public_repo`
- `repo` is definitely needed if the repository is private.
- `actions:read`
- `actions:write`
- Fine-grained PAT, GitHub App, or `GITHUB_TOKEN`: `Actions` repository permission, **write**
- Classic PAT or OAuth token: `repo` scope

### APIs Used

For the sake of transparency please note that this action uses the following API calls:

- [Create a workflow dispatch event](https://docs.github.com/en/rest/actions/workflows#create-a-workflow-dispatch-event)
- POST `/repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches`
- Permissions:
- `repo`
- `actions:write`
- [List repository workflows](https://docs.github.com/en/rest/actions/workflows#list-repository-workflows)
- GET `/repos/{owner}/{repo}/actions/workflows`
- Permissions:
- `repo`
- `actions:read`
- [List workflow runs](https://docs.github.com/en/rest/actions/workflow-runs#list-workflow-runs-for-a-repository)
- GET `/repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs`
- Permissions:
- `repo`
- [List jobs for a workflow run](https://docs.github.com/en/rest/actions/workflow-jobs#list-jobs-for-a-workflow-run)
- GET `/repos/{owner}/{repo}/actions/runs/{run_id}/jobs`
- Permissions:
- `repo`
- `actions:read`
- Sent with `return_run_details: true`, so the response carries the new run's ID and URL
- Requires github.com or GitHub Enterprise Server 3.21+, older servers cannot return the run details

For more information please see [api.ts](./src/api.ts).
Comment thread
coderabbitai[bot] marked this conversation as resolved.

## Where does this help?

If you have an action in a repository that dispatches an action on a foreign repository currently with Github API there is no way to know what the foreign run you've just dispatched is. Identifying this can be cumbersome and tricky.

The consequence of not being provided with something to identify the run is that you cannot easily wait for this run or poll the run for it's completion status (success, failure, etc).

## Flow

```ascii
┌─────────────────┐
│ │
│ Dispatch Action │
│ │
│ with unique ID │
│ │
└───────┬─────────┘
▼ ┌───────────────┐
┌────────────────┐ │ │
│ │ │ Request steps │
│ Request top 10 ├────────────────►│ │
│ │ │ for each run │
│ workflow runs │ │ │
│ │◄────────────────┤ and search │
└───────┬────────┘ Retry │ │
│ └───────┬───────┘
│ │
Timeout │ │
│ │
▼ ▼
┌──────┐ ┌───────────────┐
│ Fail │ │ Output run ID │
└──────┘ └───────────────┘
```
If you have an action in a repository that dispatches an action on a foreign repository,
you need to know which foreign run you've just dispatched before you can wait for it or
poll it for a completion status (success, failure, etc).

This Action gets you that run ID and URL as step outputs, so you can hand them straight
to something like [`await-remote-run`](https://github.com/Codex-/await-remote-run).
10 changes: 0 additions & 10 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,6 @@ inputs:
required: true
workflow_inputs:
description: A flat JSON object, only supports strings, numbers, and booleans (as per workflow inputs API).
workflow_timeout_seconds:
description: Time until giving up waiting for the start of the workflow run.
default: 300
workflow_job_steps_retry_seconds:
description: |
The interval (in seconds) to wait between retries. A linear backoff strategy is used, where the wait time
increases by this value with each attempt (e.g., 1st retry = this value, 2nd retry = 2x this value, etc.).
default: 5
distinct_id:
description: Specify a static string to use instead of a random distinct ID.

runs:
using: node24
Expand Down
Loading
Loading