Skip to content

Commit

Permalink
feat: location input
Browse files Browse the repository at this point in the history
A location input can now be specified to change the repository
where a secret will be created/updated
  • Loading branch information
gliech committed Aug 25, 2020
1 parent 25b17bd commit 25b4a18
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 19 deletions.
49 changes: 45 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ jobs:
with:
name: main
path: dist/index.js
- name: Delete secret
if: always()
uses: octokit/request-action@v2.x
with:
route: DELETE /repos/:repository/actions/secrets/:secret_name
repository: ${{ github.repository }}
secret_name: TEST_${{ github.sha }}
env:
GITHUB_TOKEN: ${{ secrets.PA_TOKEN_PIPELINE }}

test_create:
name: test secret creation
Expand Down Expand Up @@ -71,16 +80,47 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.PA_TOKEN_PIPELINE }}

- name: Delete secret
if: always()

test_repo_location:
name: test secret creation in foreign repository
runs-on: ubuntu-latest
needs: build
env:
FOREIGN_REPO: gliech/dotfiles
steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Download build artifact
uses: actions/download-artifact@v2
with:
name: main
path: dist

- name: Create a secret
id: self
uses: ./
with:
location: ${{ env.FOREIGN_REPO }}
name: TEST_${{ github.sha }}
value: test
pa_token: ${{ secrets.PA_TOKEN_PIPELINE }}

- name: Assert action output
if: steps.self.outputs.status != '201'
run: echo "::error::Expected HTTP status code 201 got
${{steps.self.outputs.status}}"; exit 1

- name: Confirm secret creation
uses: octokit/request-action@v2.x
with:
route: DELETE /repos/:repository/actions/secrets/:secret_name
repository: ${{ github.repository }}
route: GET /repos/:repository/actions/secrets/:secret_name
repository: ${{ env.FOREIGN_REPO }}
secret_name: TEST_${{ github.sha }}
env:
GITHUB_TOKEN: ${{ secrets.PA_TOKEN_PIPELINE }}


test_update:
name: test secret update
runs-on: ubuntu-latest
Expand Down Expand Up @@ -115,6 +155,7 @@ jobs:
runs-on: ubuntu-latest
needs:
- test_create
- test_repo_location
- test_update
steps:
- name: Checkout repository
Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ inputs:
description: Personal access token with permission to modify repository
secrets
required: true
location:
description: Name of the repository in the form 'owner/repo'. Defaults to
the repository in which the action is executed
required: false
name:
description: Name of the secret that should be created or updated
required: true
Expand Down
43 changes: 28 additions & 15 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,47 @@ const core = require("@actions/core");
const github = require("@actions/github");
const sodium = require('tweetsodium');

class GithubLocation {
contructor(location_input) {
if (location_input) {
const [owner, repo] = location_input.split('/')
this.data = {owner, repo}
} else {
const context = github.context;
this.data = context.repo;
}
}
toString() {
return [this.data.owner, this.data.repo].join('/')
}
}

async function run() {
try {
// Get all inputs
const pa_token = core.getInput('pa_token');
const octokit = github.getOctokit(pa_token);

const secret_name = core.getInput('name');

const secret_value = core.getInput('value');
core.setSecret(secret_value);
const input_pat = core.getInput('pa_token');
const input_location = core.getInput('location');
const input_name = core.getInput('name');
const input_value = core.getInput('value');

const context = github.context;
const secret_location = new GithubLocation(input_location)

// Retrieve repository public key and encrypt secret value
core.info(`Retrieving public key for repository ${context.repo.owner}/${context.repo.repo}`)
const { data: repo_public_key } = await octokit.actions.getRepoPublicKey(context.repo);
const octokit = github.getOctokit(input_pat);
core.info(`Retrieving public key for repository ${secret_location}`)
const { data: repo_public_key } = await octokit.actions.getRepoPublicKey(secret_location.data);

core.info("Encrypting secret value")
const plain_value_bytes = Buffer.from(secret_value);
const plain_value_bytes = Buffer.from(input_value);
const public_key_bytes = Buffer.from(repo_public_key.key, 'base64');
const secret_value_bytes = sodium.seal(plain_value_bytes, public_key_bytes);
const signed_secret_value = Buffer.from(secret_value_bytes).toString('base64');

// Create or update secret
core.info(`Setting repository secret "${secret_name}"`)
core.info(`Setting repository secret "${input_name}"`)
const { status } = await octokit.actions.createOrUpdateRepoSecret({
...context.repo,
secret_name: secret_name,
...secret_location.data,
secret_name: input_name,
encrypted_value: signed_secret_value,
key_id: repo_public_key.key_id
});
Expand All @@ -40,7 +53,7 @@ async function run() {
}

if (status in response_codes) {
core.info(`Successfully ${response_codes[status]} repository secret "${secret_name}"`)
core.info(`Successfully ${response_codes[status]} repository secret "${input_name}"`)
}

core.setOutput("status", status);
Expand Down

0 comments on commit 25b4a18

Please sign in to comment.