Skip to content
This repository has been archived by the owner on Oct 2, 2024. It is now read-only.

Support repository-scoped runner #3

Merged
merged 5 commits into from
Sep 2, 2021
Merged
Show file tree
Hide file tree
Changes from 4 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
47 changes: 34 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ GitHub Action for refreshing dummy self hosted runner.

- Create or refresh dummy runner for target organization.

**Table of Contents**

[TOC]
yoichiwo7 marked this conversation as resolved.
Show resolved Hide resolved
# Background

When you are using managed self-hosted-runner solution such as [myshoes](https://github.com/whywaita/myshoes), you'll need to add dummy runner to the target organization/repository.
Expand All @@ -16,13 +19,13 @@ However, because dummy runner is always in offline status, GitHub sever will rem
## Inputs

- Required
- `org-name`: Target organization name. (ex. cycloud-io)
- `org-name` or `repo-name`: Target organization or repository name.
- Either name must be specified. You can't set both.
- `org-name` example: cycloud-io
- `repo-name` example: cycloud-io/my-repo
- `github-access-token`: GitHub access token to use.
- You must prepare the GitHub access token. The GitHub Actions' **default token `secrets.GITHUB_TOKEN` won't work.**
- Following scope/permission is required depending on solutions you use:
- Personal Access Token: `admin:org` scope is required for the target organization.
- OAuth Apps: `admin:org` scope is required for the target organization.
- GitHub Apps: `organization_self_hosted_runners: write` permission for the target organization. ([REST API Link](https://docs.github.com/en/[email protected]/rest/reference/apps#create-an-installation-access-token-for-an-app))
- Check required scope/permission for the token [here](#required-scopepermission).
- Always use secret environment (ex. `${{ secrets.SECRET_NAME }}`). **NEVER SET THIS VALUE AS PLAIN TEXT.**
- Optional
- `runner-version`: Dummy runner version to use. If not specified, it will copy and use the version of the running runner.
Expand All @@ -35,10 +38,10 @@ For complete action definition, see [action.yaml](./action.yaml)

Following GitHub Actions workflow example shows how to use `refresh-runner-action` in your repository's workflow.

- For the first wokrlfow run, you must prepare your own dummy runner. Without it you can't run the workflow that uses `refresh-runner-action`.
- You must set following field to appropriate values.
- org-name
- github-access-token
- For the first wokrlfow run, you must prepare your own dummy runner. Without it you can't run the workflow that uses `refresh-runner-action`. See [official document](https://docs.github.com/en/[email protected]/actions/hosting-your-own-runners/adding-self-hosted-runners) for detail.
- You must set following fields to appropriate values.
- `org-name` or `repo-name` (Do not set both)
- `github-access-token`

```yaml
name: refresh-dummy-runner
Expand All @@ -59,15 +62,33 @@ jobs:
- name: Refresh runner
uses: cycloud-io/refresh-runner-action@v1
with:
# NOTE: Set to appropriate organization name.
# NOTE: Set either `org-name` or `repo-name`.
org-name: cycloud-io
#repo-name: cycloud-io/my-repo

# NOTE: Add `RUNNER_API_ACCESS_TOKEN` secret to the repository.
github-access-token: ${{ secrets.RUNNER_API_ACCESS_TOKEN }}
```


# Future Plan
## Required scope/permission

Following scope/permission is required for `github-access-token`.

- Personal Access Token
- For `org-name` - `admin:org` scope is required for target organization.
- For `repo-name` - `repo` scope is required for target repository.

- OAuth Apps
- Same as Personal Access Token.

- GitHub Apps
- For `org-name` - `organization_self_hosted_runners: write` permission is required for target organization.
- For `repo-name` - `administration: write` permission is required for target repository.


Related Links:

Following features will be added **if there are certain demands.**
- [Self-hosted runner groups](https://docs.github.com/en/[email protected]/rest/reference/actions#self-hosted-runner-groups)
- [Create an installation access token for an app](https://docs.github.com/en/[email protected]/rest/reference/apps#create-an-installation-access-token-for-an-app)

- Support repository scope runner.
36 changes: 31 additions & 5 deletions action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,24 @@ description: Creates/Refreshes self hosted runner.
inputs:
## Required Parameters
org-name:
description: Target organization name.
required: true
description: Target organization name. Either org-name or repo-name must be specified.
default: ""
required: false
repo-name:
description: |
Target repository name. Repository name must include owner: {owner}/{repo}`.
yoichiwo7 marked this conversation as resolved.
Show resolved Hide resolved
Either org-name or repo-name must be specified.
default: ""
required: false
github-access-token:
description: Github access token to use. Token should be personal access token or Github Apps generated token.
required: true

## Optional Parameters
runner-version:
description: |
Version of Github Self Hosted Runner. If not specified, it will use the version of the running runner. (NOTE: Architecture is fixed to "linux-x64")
Version of Github Self Hosted Runner.
If not specified, it will use the version of the running runner. (NOTE: Architecture is fixed to "linux-x64")
required: false
default: ''
runner-name:
Expand All @@ -30,6 +38,15 @@ runs:
# Exit on error
set -eu

if [ "${{ inputs.org-name }}" != "" ] && [ "${{ inputs.repo-name }}" != "" ]; then
echo "Error: Can't specify both org-name and repo-name."
exit 1
fi
if [ "${{ inputs.org-name }}" = "" ] && [ "${{ inputs.repo-name }}" = "" ]; then
echo "Error: Required to specify either org-name or repo-name."
exit 1
fi

# Prepare dummy runner files
mkdir actions-runner && cd actions-runner
if [ "${{ inputs.runner-version }}" = "" ]; then
Expand All @@ -48,10 +65,19 @@ runs:
echo "Prepared dummy runner version: $(./config.sh --version)"

echo "### Configure dummy runner"
RUNNER_TOKEN=$(bash ${{ github.action_path }}/script/get-runner-token.sh ${{ inputs.github-access-token }} ${GITHUB_API_URL} ${{ inputs.org-name }} )
if [ "${{ inputs.org-name }}" != "" ]; then
echo "target org: ${{ inputs.org-name }}"
RUNNER_TOKEN=$(bash ${{ github.action_path }}/script/get-org-runner-token.sh ${{ inputs.github-access-token }} ${GITHUB_API_URL} ${{ inputs.org-name }} )
TARGET_NAME=${{ inputs.org-name }}
else
echo "target repository: ${{ inputs.repo-name }}"
RUNNER_TOKEN=$(bash ${{ github.action_path }}/script/get-repo-runner-token.sh ${{ inputs.github-access-token }} ${GITHUB_API_URL} ${{ inputs.repo-name }} )
TARGET_NAME=${{ inputs.repo-name }}
fi

./config.sh \
--name ${{ inputs.runner-name }} \
--url ${GITHUB_SERVER_URL}/${{ inputs.org-name }} \
--url ${GITHUB_SERVER_URL}/${TARGET_NAME} \
--token ${RUNNER_TOKEN} \
--labels dummy-runner \
--replace \
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#!/bin/bash
set -e
set -eu

RUNNER_API_ACCESS_TOKEN=$1
API_URL=$2
ORG_NAME=$3

# API ref: https://docs.github.com/en/[email protected]/rest/reference/actions#create-a-registration-token-for-an-organization
RUNNER_TOKEN=$(curl -s \
-X POST \
-H "Accept: application/vnd.github.v3+json" \
Expand Down
17 changes: 17 additions & 0 deletions script/get-repo-runner-token.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash
set -eu

RUNNER_API_ACCESS_TOKEN=$1
API_URL=$2
# Expects to be `{owner}/{repo}`
REPO_NAME=$3

# API ref: https://docs.github.com/en/[email protected]/rest/reference/actions#create-a-registration-token-for-a-repository
RUNNER_TOKEN=$(curl -s \
-X POST \
-H "Accept: application/vnd.github.v3+json" \
-H "authorization: Bearer ${RUNNER_API_ACCESS_TOKEN}" \
${API_URL}/repos/${REPO_NAME}/actions/runners/registration-token \
| jq -r .token
)
echo -n $RUNNER_TOKEN