mirror of
https://github.com/webfactory/ssh-agent.git
synced 2026-03-15 15:59:06 +08:00
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b2f2c5354 | ||
|
|
4d06ea6a33 | ||
|
|
85353917a2 | ||
|
|
e5df661fc4 | ||
|
|
23e7ede81c | ||
|
|
edc2fe4f2e | ||
|
|
79096d29b0 | ||
|
|
5fedeb584e | ||
|
|
780d0ee9a3 | ||
|
|
43c9b3548b | ||
|
|
ee29fafb6a | ||
|
|
3dd57c80a6 | ||
|
|
9e5c1c7a9b | ||
|
|
ef0ce0cab8 | ||
|
|
5ef9e0334a | ||
|
|
8789658b02 | ||
|
|
4fcb25e7ef | ||
|
|
a82ae3cd1a | ||
|
|
a3b3049f43 | ||
|
|
716fbacac2 | ||
|
|
0a38ab0926 | ||
|
|
4d1295c53b | ||
|
|
cf56a519af | ||
|
|
9d13200510 | ||
|
|
b6c65becb0 | ||
|
|
c6eb7ee1d8 | ||
|
|
6cf6299d23 | ||
|
|
ea39f521c5 | ||
|
|
1a9af8e8e0 | ||
|
|
e181806200 | ||
|
|
e9cec5c598 |
60
.github/workflows/demo.yml
vendored
Normal file
60
.github/workflows/demo.yml
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
single_key_demo:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macOS-latest, windows-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup key
|
||||
uses: ./
|
||||
with:
|
||||
ssh-private-key: |
|
||||
${{ secrets.DEMO_KEY }}
|
||||
${{ secrets.DEMO_KEY_2 }}
|
||||
|
||||
multiple_keys_demo:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macOS-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup key
|
||||
uses: ./
|
||||
with:
|
||||
ssh-private-key: ${{ secrets.DEMO_KEY }}
|
||||
|
||||
docker_demo:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ubuntu:latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: apt update && apt install -y openssh-client
|
||||
- name: Setup key
|
||||
uses: ./
|
||||
with:
|
||||
ssh-private-key: |
|
||||
${{ secrets.DEMO_KEY }}
|
||||
${{ secrets.DEMO_KEY_2 }}
|
||||
|
||||
deployment_keys_demo:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup key
|
||||
uses: ./
|
||||
with:
|
||||
ssh-private-key: |
|
||||
${{ secrets.MPDUDE_TEST_1_DEPLOY_KEY }}
|
||||
${{ secrets.MPDUDE_TEST_2_DEPLOY_KEY }}
|
||||
- run: |
|
||||
git clone https://github.com/mpdude/test-1.git test-1-http
|
||||
git clone git@github.com:mpdude/test-1.git test-1-git
|
||||
git clone ssh://git@github.com/mpdude/test-1.git test-1-git-ssh
|
||||
git clone https://github.com/mpdude/test-2.git test-2-http
|
||||
git clone git@github.com:mpdude/test-2.git test-2-git
|
||||
git clone ssh://git@github.com/mpdude/test-2.git test-2-git-ssh
|
||||
44
CHANGELOG.md
Normal file
44
CHANGELOG.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## v0.4.1 [2020-10-07]
|
||||
|
||||
### Fixed
|
||||
|
||||
* This action no longer relies on `set-env`, which has been deprecated.
|
||||
|
||||
## v0.4.0
|
||||
|
||||
### Changed
|
||||
|
||||
* A failure to kill the agent in the post-action step will no longer fail the workflow run. That way, you can kill the agent yourself when necessary (#33).
|
||||
|
||||
## v0.3.0 [2020-05-18]
|
||||
|
||||
### Added
|
||||
|
||||
* A new post-action step will automatically clean up the running agent at the end of a job. This helps with self-hosted runners, which are non-ephemeral. (@thommyhh, #27)
|
||||
|
||||
### Changed
|
||||
|
||||
* Unless the SSH_AUTH_SOCK is configured explicitly, the SSH agent will now use a random file name for the socket. That way, multiple, concurrent SSH agents can be used on self-hosted runners. (@thommyhh, #27)
|
||||
|
||||
## v0.2.0 [2020-01-14]
|
||||
|
||||
### Added
|
||||
|
||||
* Multiple SSH keys can now be provided (#14, closes #7). Thanks to
|
||||
@webknjaz and @bradmartin for support and tests.
|
||||
|
||||
* Catch empty ssh-private-key input values and exit with a helpful
|
||||
error message right away.
|
||||
|
||||
## v0.1.0 [2019-09-15]
|
||||
|
||||
Initial release.
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 webfactory GmbH <info@webfactory.de>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
123
README.md
123
README.md
@@ -3,9 +3,15 @@
|
||||
This action
|
||||
* starts the `ssh-agent`,
|
||||
* exports the `SSH_AUTH_SOCK` environment variable,
|
||||
* loads a private SSH key into the agent and
|
||||
* loads one or several private SSH key into the agent and
|
||||
* configures `known_hosts` for GitHub.com.
|
||||
|
||||
It should work in all GitHub Actions virtual environments, including container-based workflows.
|
||||
|
||||
Windows and Docker support is, however, somewhat new. Since we have little feedback from the field, things might not run so smooth for you as we'd hope. If Windows and/or Docker-based workflows work well for you, leave a :+1: at https://github.com/webfactory/ssh-agent/pull/17.
|
||||
|
||||
Also, using multiple GitHub deployment keys is supported; keys are mapped to repositories by using SSH key comments (see below).
|
||||
|
||||
## Why?
|
||||
|
||||
When running a GitHub Action workflow to stage your project, run tests or build images, you might need to fetch additional libraries or _vendors_ from private repositories.
|
||||
@@ -15,10 +21,10 @@ GitHub Actions only have access to the repository they run for. So, in order to
|
||||
## Usage
|
||||
|
||||
1. Create an SSH key with sufficient access privileges. For security reasons, don't use your personal SSH key but set up a dedicated one for use in GitHub Actions. See below for a few hints if you are unsure about this step.
|
||||
2. In your repository, go to the *Settings > Secrets* menu and create a new secret called `SSH_PRIVATE_KEY`. Put the *unencrypted private* SSH key in `PEM` format into the contents field. <br>
|
||||
This key should start with `-----BEGIN RSA PRIVATE KEY-----`, consist of many lines and ends with `-----END RSA PRIVATE KEY-----`.
|
||||
You can just copy the key as-is from the private key file.
|
||||
3. In your workflow definition file, add the following step. Preferably this would be rather on top, near the `actions/checkout@v1` line.
|
||||
2. Make sure you don't have a passphrase set on the private key.
|
||||
3. In your repository, go to the *Settings > Secrets* menu and create a new secret. In this example, we'll call it `SSH_PRIVATE_KEY`. Put the contents of the *private* SSH key file into the contents field. <br>
|
||||
This key should start with `-----BEGIN ... PRIVATE KEY-----`, consist of many lines and ends with `-----END ... PRIVATE KEY-----`.
|
||||
4. In your workflow definition file, add the following step. Preferably this would be rather on top, near the `actions/checkout@v2` line.
|
||||
|
||||
```yaml
|
||||
# .github/workflows/my-workflow.yml
|
||||
@@ -26,39 +32,96 @@ jobs:
|
||||
my_job:
|
||||
...
|
||||
steps:
|
||||
- actions/checkout@v1
|
||||
- uses: webfactory/ssh-agent@v0.1
|
||||
- actions/checkout@v2
|
||||
# Make sure the @v0.5.0 matches the current version of the
|
||||
# action
|
||||
- uses: webfactory/ssh-agent@v0.5.0
|
||||
with:
|
||||
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||
- ... other steps
|
||||
```
|
||||
4. If, for some reason, you need to change the location of the SSH agent socket, you can use the `ssh-auth-sock` input to provide a path.
|
||||
5. If, for some reason, you need to change the location of the SSH agent socket, you can use the `ssh-auth-sock` input to provide a path.
|
||||
|
||||
## Known issues and limitations
|
||||
### Using Multiple Keys
|
||||
|
||||
### Works for the current job only
|
||||
There are cases where you might need to use multiple keys. For example, "[deploy keys](https://docs.github.com/en/developers/overview/managing-deploy-keys#deploy-keys)" might be limited to a single repository, so you'll need several of them.
|
||||
|
||||
You can set up different keys as different secrets and pass them all to the action like so:
|
||||
|
||||
```yaml
|
||||
# ... contens as before
|
||||
- uses: webfactory/ssh-agent@v0.5.0
|
||||
with:
|
||||
ssh-private-key: |
|
||||
${{ secrets.FIRST_KEY }}
|
||||
${{ secrets.NEXT_KEY }}
|
||||
${{ secrets.ANOTHER_KEY }}
|
||||
```
|
||||
|
||||
The `ssh-agent` will load all of the keys and try each one in order when establishing SSH connections.
|
||||
|
||||
There's one **caveat**, though: SSH servers may abort the connection attempt after a number of mismatching keys have been presented. So if, for example, you have six different keys loaded into the `ssh-agent`, but the server aborts after five unknown keys, the last key (which might be the right one) will never even be tried. But when you're using GitHub Deploy Keys, read on!
|
||||
|
||||
### Support for GitHub Deploy Keys
|
||||
|
||||
When using **Github deploy keys**, GitHub servers will accept the _first_ known key. But since deploy keys are scoped to a single repository, this might not be the key needed to access a particular repository. Thus, you will get the error message `fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.` if the wrong key/repository combination is tried.
|
||||
|
||||
To support picking the right key in this use case, this action scans _key comments_ and will set up extra Git and SSH configuration to make things work.
|
||||
|
||||
1. When creating the deploy key for a repository like `git@github.com:owner/repo.git` or `https://github.com/owner/repo`, put that URL into the key comment.
|
||||
2. After keys have been added to the agent, this action will scan the key comments.
|
||||
3. For key comments containing such URLs, a Git config setting is written that uses [`url.<base>.insteadof`](https://git-scm.com/docs/git-config#Documentation/git-config.txt-urlltbasegtinsteadOf). It will redirect `git` requests to URLs starting with either `https://github.com/owner/repo` or `git@github.com:owner/repo` to a fake hostname/URL like `git@...some.hash...:owner/repo`.
|
||||
4. An SSH configuration section is generated that applies to the fake hostname. It will map the SSH connection back to `github.com`, while at the same time pointing SSH to a file containing the appropriate key's public part. That will make SSH use the right key when connecting to GitHub.com.
|
||||
|
||||
## Exported variables
|
||||
The action exports the `SSH_AUTH_SOCK` and `SSH_AGENT_PID` environment variables through the Github Actions core module.
|
||||
The `$SSH_AUTH_SOCK` is used by several applications like git or rsync to connect to the SSH authentication agent.
|
||||
The `$SSH_AGENT_PID` contains the process id of the agent. This is used to kill the agent in post job action.
|
||||
|
||||
## Known Issues and Limitations
|
||||
|
||||
### Works for the Current Job Only
|
||||
|
||||
Since each job [runs in a fresh instance](https://help.github.com/en/articles/about-github-actions#job) of the virtual environment, the SSH key will only be available in the job where this action has been referenced. You can, of course, add the action in multiple jobs or even workflows. All instances can use the same `SSH_PRIVATE_KEY` secret.
|
||||
|
||||
### SSH private key format
|
||||
### SSH Private Key Format
|
||||
|
||||
If the private key is not in the `PEM` format, you will see an `Error loading key "(stdin)": invalid format` message.
|
||||
|
||||
Use `ssh-keygen -p -f path/to/your/key -m pem` to convert your key file to `PEM`, but be sure to make a backup of the file first 😉.
|
||||
|
||||
## Creating SSH keys
|
||||
## What this Action *cannot* do for you
|
||||
|
||||
In order to create a new SSH key, run `ssh-keygen -t rsa -b 4096 -m pem -f path/to/keyfile`. This will prompt you for a key passphrase and save the key in `path/to/keyfile`.
|
||||
The following items are not issues, but beyond what this Action is supposed to do.
|
||||
|
||||
Having a passphrase is a good thing, since it will keep the key encrypted on your disk. When configuring the secret `SSH_PRIVATE_KEY` value in your repository, however, you will need the private key *unencrypted*.
|
||||
### Work on Remote Machines
|
||||
|
||||
To show the private key unencrypted, run `openssl rsa -in path/to/key -outform pem`.
|
||||
When using `ssh` to connect from the GitHub Action worker node to another machine, you *can* forward the SSH Agent socket and use your private key on the other (remote) machine. However, this Action will not configure `known_hosts` or other SSH settings on the remote machine for you.
|
||||
|
||||
## Authorizing a key
|
||||
### Provide the SSH Key as a File
|
||||
|
||||
This Action is designed to pass the SSH key directly into `ssh-agent`; that is, the key is available in memory on the GitHub Action worker node, but never written to disk. As a consequence, you _cannot_ pass the key as a build argument or a mounted file into Docker containers that you build or run on the worker node. You _can_, however, mount the `ssh-agent` Unix socket into a Docker container that you _run_, set up the `SSH_AUTH_SOCK` env var and then use SSH from within the container (see #11).
|
||||
|
||||
### Run `ssh-keyscan` to Add Host Keys for Additional Hosts
|
||||
|
||||
If you want to use `ssh-keyscan` to add additional hosts (that you own/know) to the `known_hosts` file, you can do so with a single shell line in your Action definition. You don't really need this Action to do this for you.
|
||||
|
||||
As a side note, using `ssh-keyscan` without proper key verification is susceptible to man-in-the-middle attacks. You might prefer putting your _known_ SSH host key in your own Action files to add it to the `known_hosts` file. The SSH host key is not secret and can safely be committed into the repo.
|
||||
|
||||
## Creating SSH Keys
|
||||
|
||||
In order to create a new SSH key, run `ssh-keygen -t ed25519 -a 100 -f path/to/keyfile`, as suggested in [this blog post](https://stribika.github.io/2015/01/04/secure-secure-shell.html).
|
||||
If you need to work with some older server software and need RSA keys, tr `ssh-keygen -t rsa -b 4096 -o -f path/to/keyfile` instead.
|
||||
|
||||
Both commands will prompt you for a key passphrase and save the key in `path/to/keyfile`.
|
||||
In general, having a passphrase is a good thing, since it will keep the key encrypted on your disk. When using the key with this action, however, you need to make sure you don't
|
||||
specify a passphrase: The key must be usable without reading the passphrase from input. Since the key itself is stored using GitHub's "Secret" feature, it should be fairly safe anyway.
|
||||
|
||||
## Authorizing a Key
|
||||
|
||||
To actually grant the SSH key access, you can – on GitHub – use at least two ways:
|
||||
|
||||
* [Deploy keys](https://developer.github.com/v3/guides/managing-deploy-keys/#deploy-keys) can be added to individual GitHub repositories. They can give read and/or write access to the particular repository. When pulling a lot of dependencies, however, you'll end up adding the key in many places. Rotating the key probably becomes difficult.
|
||||
* [Deploy keys](https://developer.github.com/v3/guides/managing-deploy-keys/#deploy-keys) can be added to individual GitHub repositories. They can give read and/or write access to the particular repository. When pulling a lot of dependencies, however, you'll end up adding the key in many places. Rotating the key probably becomes difficult. The deploy key needs to be added to the private repository that is being fetched as a private dependency.
|
||||
|
||||
* A [machine user](https://developer.github.com/v3/guides/managing-deploy-keys/#machine-users) can be used for more fine-grained permissions management and have access to multiple repositories with just one instance of the key being registered. It will, however, count against your number of users on paid GitHub plans.
|
||||
|
||||
@@ -67,11 +130,29 @@ To actually grant the SSH key access, you can – on GitHub – use at least two
|
||||
As a note to my future self, in order to work on this repo:
|
||||
|
||||
* Clone it
|
||||
* Run `npm install` to fetch dependencies
|
||||
* Run `yarn install` to fetch dependencies
|
||||
* _hack hack hack_
|
||||
* `node index.js` (inputs are passed through `INPUT_` env vars, but how to set `ssh-private-key`?)
|
||||
* Run `./node_modules/.bin/ncc build index.js` to update `dist/index.js`, which is the file actually run
|
||||
* `node index.js`. Inputs are passed through `INPUT_` env vars with their names uppercased.
|
||||
|
||||
On *nix use:
|
||||
```bash
|
||||
env "INPUT_SSH-PRIVATE-KEY=\`cat file\`" node index.js
|
||||
```
|
||||
|
||||
On Windows (cmd):
|
||||
```cmd
|
||||
set /P INPUT_SSH-PRIVATE-KEY=< file
|
||||
node index.js
|
||||
```
|
||||
|
||||
On Windows (PowerShell):
|
||||
```ps
|
||||
${env:INPUT_SSH-PRIVATE-KEY} = (Get-Content .\test-keys -Raw); node index.js
|
||||
node index.js
|
||||
```
|
||||
* Run `npm run build` to update `dist/*`, which holds the files actually run
|
||||
* Read https://help.github.com/en/articles/creating-a-javascript-action if unsure.
|
||||
* Maybe update the README example when publishing a new version.
|
||||
|
||||
## Credits, Copyright and License
|
||||
|
||||
@@ -82,4 +163,4 @@ developer looking for new challenges, we'd like to hear from you!
|
||||
- <https://www.webfactory.de>
|
||||
- <https://twitter.com/webfactory>
|
||||
|
||||
Copyright 2019 webfactory GmbH, Bonn. Code released under [the MIT license](LICENSE).
|
||||
Copyright 2019 – 2021 webfactory GmbH, Bonn. Code released under [the MIT license](LICENSE).
|
||||
|
||||
@@ -6,10 +6,10 @@ inputs:
|
||||
required: true
|
||||
ssh-auth-sock:
|
||||
description: 'Where to place the SSH Agent auth socket'
|
||||
default: /tmp/ssh-auth.sock
|
||||
runs:
|
||||
using: 'node12'
|
||||
main: 'dist/index.js'
|
||||
post: 'dist/cleanup.js'
|
||||
branding:
|
||||
icon: loader
|
||||
color: 'yellow'
|
||||
|
||||
11
cleanup.js
Normal file
11
cleanup.js
Normal file
@@ -0,0 +1,11 @@
|
||||
const core = require('@actions/core')
|
||||
const { execSync } = require('child_process')
|
||||
|
||||
try {
|
||||
// Kill the started SSH agent
|
||||
console.log('Stopping SSH agent')
|
||||
execSync('kill ${SSH_AGENT_PID}', { stdio: 'inherit' })
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
console.log('Error stopping the SSH agent, proceeding anyway');
|
||||
}
|
||||
485
dist/cleanup.js
vendored
Normal file
485
dist/cleanup.js
vendored
Normal file
@@ -0,0 +1,485 @@
|
||||
module.exports =
|
||||
/******/ (function(modules, runtime) { // webpackBootstrap
|
||||
/******/ "use strict";
|
||||
/******/ // The module cache
|
||||
/******/ var installedModules = {};
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/
|
||||
/******/ // Check if module is in cache
|
||||
/******/ if(installedModules[moduleId]) {
|
||||
/******/ return installedModules[moduleId].exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = installedModules[moduleId] = {
|
||||
/******/ i: moduleId,
|
||||
/******/ l: false,
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Flag the module as loaded
|
||||
/******/ module.l = true;
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/******/
|
||||
/******/ __webpack_require__.ab = __dirname + "/";
|
||||
/******/
|
||||
/******/ // the startup function
|
||||
/******/ function startup() {
|
||||
/******/ // Load entry module and return exports
|
||||
/******/ return __webpack_require__(175);
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // run startup
|
||||
/******/ return startup();
|
||||
/******/ })
|
||||
/************************************************************************/
|
||||
/******/ ({
|
||||
|
||||
/***/ 82:
|
||||
/***/ (function(__unusedmodule, exports) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// We use any as a valid input type
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/**
|
||||
* Sanitizes an input into a string so it can be passed into issueCommand safely
|
||||
* @param input input to sanitize into a string
|
||||
*/
|
||||
function toCommandValue(input) {
|
||||
if (input === null || input === undefined) {
|
||||
return '';
|
||||
}
|
||||
else if (typeof input === 'string' || input instanceof String) {
|
||||
return input;
|
||||
}
|
||||
return JSON.stringify(input);
|
||||
}
|
||||
exports.toCommandValue = toCommandValue;
|
||||
//# sourceMappingURL=utils.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 87:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("os");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 102:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// For internal use, subject to change.
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
// We use any as a valid input type
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
const fs = __importStar(__webpack_require__(747));
|
||||
const os = __importStar(__webpack_require__(87));
|
||||
const utils_1 = __webpack_require__(82);
|
||||
function issueCommand(command, message) {
|
||||
const filePath = process.env[`GITHUB_${command}`];
|
||||
if (!filePath) {
|
||||
throw new Error(`Unable to find environment variable for file command ${command}`);
|
||||
}
|
||||
if (!fs.existsSync(filePath)) {
|
||||
throw new Error(`Missing file at path: ${filePath}`);
|
||||
}
|
||||
fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, {
|
||||
encoding: 'utf8'
|
||||
});
|
||||
}
|
||||
exports.issueCommand = issueCommand;
|
||||
//# sourceMappingURL=file-command.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 129:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("child_process");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 175:
|
||||
/***/ (function(__unusedmodule, __unusedexports, __webpack_require__) {
|
||||
|
||||
const core = __webpack_require__(470)
|
||||
const { execSync } = __webpack_require__(129)
|
||||
|
||||
try {
|
||||
// Kill the started SSH agent
|
||||
console.log('Stopping SSH agent')
|
||||
execSync('kill ${SSH_AGENT_PID}', { stdio: 'inherit' })
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
console.log('Error stopping the SSH agent, proceeding anyway');
|
||||
}
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 431:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const os = __importStar(__webpack_require__(87));
|
||||
const utils_1 = __webpack_require__(82);
|
||||
/**
|
||||
* Commands
|
||||
*
|
||||
* Command Format:
|
||||
* ::name key=value,key=value::message
|
||||
*
|
||||
* Examples:
|
||||
* ::warning::This is the message
|
||||
* ::set-env name=MY_VAR::some value
|
||||
*/
|
||||
function issueCommand(command, properties, message) {
|
||||
const cmd = new Command(command, properties, message);
|
||||
process.stdout.write(cmd.toString() + os.EOL);
|
||||
}
|
||||
exports.issueCommand = issueCommand;
|
||||
function issue(name, message = '') {
|
||||
issueCommand(name, {}, message);
|
||||
}
|
||||
exports.issue = issue;
|
||||
const CMD_STRING = '::';
|
||||
class Command {
|
||||
constructor(command, properties, message) {
|
||||
if (!command) {
|
||||
command = 'missing.command';
|
||||
}
|
||||
this.command = command;
|
||||
this.properties = properties;
|
||||
this.message = message;
|
||||
}
|
||||
toString() {
|
||||
let cmdStr = CMD_STRING + this.command;
|
||||
if (this.properties && Object.keys(this.properties).length > 0) {
|
||||
cmdStr += ' ';
|
||||
let first = true;
|
||||
for (const key in this.properties) {
|
||||
if (this.properties.hasOwnProperty(key)) {
|
||||
const val = this.properties[key];
|
||||
if (val) {
|
||||
if (first) {
|
||||
first = false;
|
||||
}
|
||||
else {
|
||||
cmdStr += ',';
|
||||
}
|
||||
cmdStr += `${key}=${escapeProperty(val)}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cmdStr += `${CMD_STRING}${escapeData(this.message)}`;
|
||||
return cmdStr;
|
||||
}
|
||||
}
|
||||
function escapeData(s) {
|
||||
return utils_1.toCommandValue(s)
|
||||
.replace(/%/g, '%25')
|
||||
.replace(/\r/g, '%0D')
|
||||
.replace(/\n/g, '%0A');
|
||||
}
|
||||
function escapeProperty(s) {
|
||||
return utils_1.toCommandValue(s)
|
||||
.replace(/%/g, '%25')
|
||||
.replace(/\r/g, '%0D')
|
||||
.replace(/\n/g, '%0A')
|
||||
.replace(/:/g, '%3A')
|
||||
.replace(/,/g, '%2C');
|
||||
}
|
||||
//# sourceMappingURL=command.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 470:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const command_1 = __webpack_require__(431);
|
||||
const file_command_1 = __webpack_require__(102);
|
||||
const utils_1 = __webpack_require__(82);
|
||||
const os = __importStar(__webpack_require__(87));
|
||||
const path = __importStar(__webpack_require__(622));
|
||||
/**
|
||||
* The code to exit an action
|
||||
*/
|
||||
var ExitCode;
|
||||
(function (ExitCode) {
|
||||
/**
|
||||
* A code indicating that the action was successful
|
||||
*/
|
||||
ExitCode[ExitCode["Success"] = 0] = "Success";
|
||||
/**
|
||||
* A code indicating that the action was a failure
|
||||
*/
|
||||
ExitCode[ExitCode["Failure"] = 1] = "Failure";
|
||||
})(ExitCode = exports.ExitCode || (exports.ExitCode = {}));
|
||||
//-----------------------------------------------------------------------
|
||||
// Variables
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Sets env variable for this action and future actions in the job
|
||||
* @param name the name of the variable to set
|
||||
* @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function exportVariable(name, val) {
|
||||
const convertedVal = utils_1.toCommandValue(val);
|
||||
process.env[name] = convertedVal;
|
||||
const filePath = process.env['GITHUB_ENV'] || '';
|
||||
if (filePath) {
|
||||
const delimiter = '_GitHubActionsFileCommandDelimeter_';
|
||||
const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`;
|
||||
file_command_1.issueCommand('ENV', commandValue);
|
||||
}
|
||||
else {
|
||||
command_1.issueCommand('set-env', { name }, convertedVal);
|
||||
}
|
||||
}
|
||||
exports.exportVariable = exportVariable;
|
||||
/**
|
||||
* Registers a secret which will get masked from logs
|
||||
* @param secret value of the secret
|
||||
*/
|
||||
function setSecret(secret) {
|
||||
command_1.issueCommand('add-mask', {}, secret);
|
||||
}
|
||||
exports.setSecret = setSecret;
|
||||
/**
|
||||
* Prepends inputPath to the PATH (for this action and future actions)
|
||||
* @param inputPath
|
||||
*/
|
||||
function addPath(inputPath) {
|
||||
const filePath = process.env['GITHUB_PATH'] || '';
|
||||
if (filePath) {
|
||||
file_command_1.issueCommand('PATH', inputPath);
|
||||
}
|
||||
else {
|
||||
command_1.issueCommand('add-path', {}, inputPath);
|
||||
}
|
||||
process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;
|
||||
}
|
||||
exports.addPath = addPath;
|
||||
/**
|
||||
* Gets the value of an input. The value is also trimmed.
|
||||
*
|
||||
* @param name name of the input to get
|
||||
* @param options optional. See InputOptions.
|
||||
* @returns string
|
||||
*/
|
||||
function getInput(name, options) {
|
||||
const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || '';
|
||||
if (options && options.required && !val) {
|
||||
throw new Error(`Input required and not supplied: ${name}`);
|
||||
}
|
||||
return val.trim();
|
||||
}
|
||||
exports.getInput = getInput;
|
||||
/**
|
||||
* Sets the value of an output.
|
||||
*
|
||||
* @param name name of the output to set
|
||||
* @param value value to store. Non-string values will be converted to a string via JSON.stringify
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function setOutput(name, value) {
|
||||
command_1.issueCommand('set-output', { name }, value);
|
||||
}
|
||||
exports.setOutput = setOutput;
|
||||
/**
|
||||
* Enables or disables the echoing of commands into stdout for the rest of the step.
|
||||
* Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.
|
||||
*
|
||||
*/
|
||||
function setCommandEcho(enabled) {
|
||||
command_1.issue('echo', enabled ? 'on' : 'off');
|
||||
}
|
||||
exports.setCommandEcho = setCommandEcho;
|
||||
//-----------------------------------------------------------------------
|
||||
// Results
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Sets the action status to failed.
|
||||
* When the action exits it will be with an exit code of 1
|
||||
* @param message add error issue message
|
||||
*/
|
||||
function setFailed(message) {
|
||||
process.exitCode = ExitCode.Failure;
|
||||
error(message);
|
||||
}
|
||||
exports.setFailed = setFailed;
|
||||
//-----------------------------------------------------------------------
|
||||
// Logging Commands
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Gets whether Actions Step Debug is on or not
|
||||
*/
|
||||
function isDebug() {
|
||||
return process.env['RUNNER_DEBUG'] === '1';
|
||||
}
|
||||
exports.isDebug = isDebug;
|
||||
/**
|
||||
* Writes debug message to user log
|
||||
* @param message debug message
|
||||
*/
|
||||
function debug(message) {
|
||||
command_1.issueCommand('debug', {}, message);
|
||||
}
|
||||
exports.debug = debug;
|
||||
/**
|
||||
* Adds an error issue
|
||||
* @param message error issue message. Errors will be converted to string via toString()
|
||||
*/
|
||||
function error(message) {
|
||||
command_1.issue('error', message instanceof Error ? message.toString() : message);
|
||||
}
|
||||
exports.error = error;
|
||||
/**
|
||||
* Adds an warning issue
|
||||
* @param message warning issue message. Errors will be converted to string via toString()
|
||||
*/
|
||||
function warning(message) {
|
||||
command_1.issue('warning', message instanceof Error ? message.toString() : message);
|
||||
}
|
||||
exports.warning = warning;
|
||||
/**
|
||||
* Writes info to log with console.log.
|
||||
* @param message info message
|
||||
*/
|
||||
function info(message) {
|
||||
process.stdout.write(message + os.EOL);
|
||||
}
|
||||
exports.info = info;
|
||||
/**
|
||||
* Begin an output group.
|
||||
*
|
||||
* Output until the next `groupEnd` will be foldable in this group
|
||||
*
|
||||
* @param name The name of the output group
|
||||
*/
|
||||
function startGroup(name) {
|
||||
command_1.issue('group', name);
|
||||
}
|
||||
exports.startGroup = startGroup;
|
||||
/**
|
||||
* End an output group.
|
||||
*/
|
||||
function endGroup() {
|
||||
command_1.issue('endgroup');
|
||||
}
|
||||
exports.endGroup = endGroup;
|
||||
/**
|
||||
* Wrap an asynchronous function call in a group.
|
||||
*
|
||||
* Returns the same type as the function itself.
|
||||
*
|
||||
* @param name The name of the group
|
||||
* @param fn The function to wrap in the group
|
||||
*/
|
||||
function group(name, fn) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
startGroup(name);
|
||||
let result;
|
||||
try {
|
||||
result = yield fn();
|
||||
}
|
||||
finally {
|
||||
endGroup();
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
exports.group = group;
|
||||
//-----------------------------------------------------------------------
|
||||
// Wrapper action state
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Saves state for current action, the state can only be retrieved by this action's post job execution.
|
||||
*
|
||||
* @param name name of the state to store
|
||||
* @param value value to store. Non-string values will be converted to a string via JSON.stringify
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function saveState(name, value) {
|
||||
command_1.issueCommand('save-state', { name }, value);
|
||||
}
|
||||
exports.saveState = saveState;
|
||||
/**
|
||||
* Gets the value of an state set by this action's main execution.
|
||||
*
|
||||
* @param name name of the state to get
|
||||
* @returns string
|
||||
*/
|
||||
function getState(name) {
|
||||
return process.env[`STATE_${name}`] || '';
|
||||
}
|
||||
exports.getState = getState;
|
||||
//# sourceMappingURL=core.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 622:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("path");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 747:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("fs");
|
||||
|
||||
/***/ })
|
||||
|
||||
/******/ });
|
||||
319
dist/index.js
vendored
319
dist/index.js
vendored
@@ -43,6 +43,32 @@ module.exports =
|
||||
/************************************************************************/
|
||||
/******/ ({
|
||||
|
||||
/***/ 82:
|
||||
/***/ (function(__unusedmodule, exports) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// We use any as a valid input type
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/**
|
||||
* Sanitizes an input into a string so it can be passed into issueCommand safely
|
||||
* @param input input to sanitize into a string
|
||||
*/
|
||||
function toCommandValue(input) {
|
||||
if (input === null || input === undefined) {
|
||||
return '';
|
||||
}
|
||||
else if (typeof input === 'string' || input instanceof String) {
|
||||
return input;
|
||||
}
|
||||
return JSON.stringify(input);
|
||||
}
|
||||
exports.toCommandValue = toCommandValue;
|
||||
//# sourceMappingURL=utils.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 87:
|
||||
/***/ (function(module) {
|
||||
|
||||
@@ -50,26 +76,133 @@ module.exports = require("os");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 102:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// For internal use, subject to change.
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
// We use any as a valid input type
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
const fs = __importStar(__webpack_require__(747));
|
||||
const os = __importStar(__webpack_require__(87));
|
||||
const utils_1 = __webpack_require__(82);
|
||||
function issueCommand(command, message) {
|
||||
const filePath = process.env[`GITHUB_${command}`];
|
||||
if (!filePath) {
|
||||
throw new Error(`Unable to find environment variable for file command ${command}`);
|
||||
}
|
||||
if (!fs.existsSync(filePath)) {
|
||||
throw new Error(`Missing file at path: ${filePath}`);
|
||||
}
|
||||
fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, {
|
||||
encoding: 'utf8'
|
||||
});
|
||||
}
|
||||
exports.issueCommand = issueCommand;
|
||||
//# sourceMappingURL=file-command.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 104:
|
||||
/***/ (function(__unusedmodule, __unusedexports, __webpack_require__) {
|
||||
|
||||
const core = __webpack_require__(470);
|
||||
const child_process = __webpack_require__(129);
|
||||
const fs = __webpack_require__(747);
|
||||
const os = __webpack_require__(87);
|
||||
const crypto = __webpack_require__(417);
|
||||
|
||||
try {
|
||||
console.log("Adding GitHub.com keys to /home/runner/ssh_known_hosts");
|
||||
fs.mkdirSync('/home/runner/.ssh', { recursive: true});
|
||||
fs.appendFileSync('/home/runner/.ssh/known_hosts', '\ngithub.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==\n');
|
||||
fs.appendFileSync('/home/runner/.ssh/known_hosts', '\ngithub.com ssh-dss AAAAB3NzaC1kc3MAAACBANGFW2P9xlGU3zWrymJgI/lKo//ZW2WfVtmbsUZJ5uyKArtlQOT2+WRhcg4979aFxgKdcsqAYW3/LS1T2km3jYW/vr4Uzn+dXWODVk5VlUiZ1HFOHf6s6ITcZvjvdbp6ZbpM+DuJT7Bw+h5Fx8Qt8I16oCZYmAPJRtu46o9C2zk1AAAAFQC4gdFGcSbp5Gr0Wd5Ay/jtcldMewAAAIATTgn4sY4Nem/FQE+XJlyUQptPWMem5fwOcWtSXiTKaaN0lkk2p2snz+EJvAGXGq9dTSWHyLJSM2W6ZdQDqWJ1k+cL8CARAqL+UMwF84CR0m3hj+wtVGD/J4G5kW2DBAf4/bqzP4469lT+dF2FRQ2L9JKXrCWcnhMtJUvua8dvnwAAAIB6C4nQfAA7x8oLta6tT+oCk2WQcydNsyugE8vLrHlogoWEicla6cWPk7oXSspbzUcfkjN3Qa6e74PhRkc7JdSdAlFzU3m7LMkXo1MHgkqNX8glxWNVqBSc0YRdbFdTkL0C6gtpklilhvuHQCdbgB3LBAikcRkDp+FCVkUgPC/7Rw==\n');
|
||||
const privateKey = core.getInput('ssh-private-key');
|
||||
|
||||
if (!privateKey) {
|
||||
core.setFailed("The ssh-private-key argument is empty. Maybe the secret has not been configured, or you are using a wrong secret name in your workflow file.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var home;
|
||||
|
||||
if (process.env['OS'] == 'Windows_NT') {
|
||||
console.log('Preparing ssh-agent service on Windows');
|
||||
child_process.execSync('sc config ssh-agent start=demand', { stdio: 'inherit' });
|
||||
|
||||
home = os.homedir();
|
||||
} else {
|
||||
// Use getent() system call, since this is what ssh does; makes a difference in Docker-based
|
||||
// Action runs, where $HOME is different from the pwent
|
||||
var { homedir: home } = os.userInfo();
|
||||
}
|
||||
|
||||
const homeSsh = home + '/.ssh';
|
||||
|
||||
console.log(`Adding GitHub.com keys to ${homeSsh}/known_hosts`);
|
||||
fs.mkdirSync(homeSsh, { recursive: true });
|
||||
fs.appendFileSync(`${homeSsh}/known_hosts`, '\ngithub.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==\n');
|
||||
fs.appendFileSync(`${homeSsh}/known_hosts`, '\ngithub.com ssh-dss AAAAB3NzaC1kc3MAAACBANGFW2P9xlGU3zWrymJgI/lKo//ZW2WfVtmbsUZJ5uyKArtlQOT2+WRhcg4979aFxgKdcsqAYW3/LS1T2km3jYW/vr4Uzn+dXWODVk5VlUiZ1HFOHf6s6ITcZvjvdbp6ZbpM+DuJT7Bw+h5Fx8Qt8I16oCZYmAPJRtu46o9C2zk1AAAAFQC4gdFGcSbp5Gr0Wd5Ay/jtcldMewAAAIATTgn4sY4Nem/FQE+XJlyUQptPWMem5fwOcWtSXiTKaaN0lkk2p2snz+EJvAGXGq9dTSWHyLJSM2W6ZdQDqWJ1k+cL8CARAqL+UMwF84CR0m3hj+wtVGD/J4G5kW2DBAf4/bqzP4469lT+dF2FRQ2L9JKXrCWcnhMtJUvua8dvnwAAAIB6C4nQfAA7x8oLta6tT+oCk2WQcydNsyugE8vLrHlogoWEicla6cWPk7oXSspbzUcfkjN3Qa6e74PhRkc7JdSdAlFzU3m7LMkXo1MHgkqNX8glxWNVqBSc0YRdbFdTkL0C6gtpklilhvuHQCdbgB3LBAikcRkDp+FCVkUgPC/7Rw==\n');
|
||||
|
||||
console.log("Starting ssh-agent");
|
||||
const authSock = core.getInput('ssh-auth-sock');
|
||||
child_process.execFileSync('ssh-agent', ['-a', authSock]);
|
||||
core.exportVariable('SSH_AUTH_SOCK', authSock);
|
||||
let sshAgentOutput = ''
|
||||
if (authSock && authSock.length > 0) {
|
||||
sshAgentOutput = child_process.execFileSync('ssh-agent', ['-a', authSock]);
|
||||
} else {
|
||||
sshAgentOutput = child_process.execFileSync('ssh-agent')
|
||||
}
|
||||
|
||||
// Extract auth socket path and agent pid and set them as job variables
|
||||
const lines = sshAgentOutput.toString().split("\n")
|
||||
for (const lineNumber in lines) {
|
||||
const matches = /^(SSH_AUTH_SOCK|SSH_AGENT_PID)=(.*); export \1/.exec(lines[lineNumber])
|
||||
if (matches && matches.length > 0) {
|
||||
core.exportVariable(matches[1], matches[2])
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Adding private key to agent");
|
||||
child_process.execSync('ssh-add -', { input: core.getInput('ssh-private-key') });
|
||||
privateKey.split(/(?=-----BEGIN)/).forEach(function(key) {
|
||||
child_process.execSync('ssh-add -', { input: key.trim() + "\n" });
|
||||
});
|
||||
|
||||
console.log("Keys added:");
|
||||
child_process.execSync('ssh-add -l', { stdio: 'inherit' });
|
||||
|
||||
child_process.execFileSync('ssh-add', ['-L']).toString().split(/\r?\n/).forEach(function(key) {
|
||||
let parts = key.match(/\bgithub.com[:/](.*)(?:\.git)?\b/);
|
||||
|
||||
if (parts == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
let ownerAndRepo = parts[1];
|
||||
let sha256 = crypto.createHash('sha256').update(key).digest('hex');
|
||||
|
||||
fs.writeFileSync(`${homeSsh}/${sha256}`, key + "\n", { mode: '600' });
|
||||
|
||||
child_process.execSync(`git config --global --replace-all url."git@${sha256}:${ownerAndRepo}".insteadOf "https://github.com/${ownerAndRepo}"`);
|
||||
child_process.execSync(`git config --global --add url."git@${sha256}:${ownerAndRepo}".insteadOf "git@github.com:${ownerAndRepo}"`);
|
||||
child_process.execSync(`git config --global --add url."git@${sha256}:${ownerAndRepo}".insteadOf "ssh://git@github.com/${ownerAndRepo}"`);
|
||||
|
||||
let sshConfig = `\nHost ${sha256}\n`
|
||||
+ ` HostName github.com\n`
|
||||
+ ` User git\n`
|
||||
+ ` IdentityFile ${homeSsh}/${sha256}\n`
|
||||
+ ` IdentitiesOnly yes\n`;
|
||||
|
||||
fs.appendFileSync(`${homeSsh}/config`, sshConfig);
|
||||
|
||||
console.log(`Added deploy-key mapping: Use key "${key}" for GitHub repository ${ownerAndRepo}`);
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
core.setFailed(error.message);
|
||||
}
|
||||
@@ -84,22 +217,37 @@ module.exports = require("child_process");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 417:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("crypto");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 431:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const os = __webpack_require__(87);
|
||||
const os = __importStar(__webpack_require__(87));
|
||||
const utils_1 = __webpack_require__(82);
|
||||
/**
|
||||
* Commands
|
||||
*
|
||||
* Command Format:
|
||||
* ##[name key=value;key=value]message
|
||||
* ::name key=value,key=value::message
|
||||
*
|
||||
* Examples:
|
||||
* ##[warning]This is the user warning message
|
||||
* ##[set-secret name=mypassword]definitelyNotAPassword!
|
||||
* ::warning::This is the message
|
||||
* ::set-env name=MY_VAR::some value
|
||||
*/
|
||||
function issueCommand(command, properties, message) {
|
||||
const cmd = new Command(command, properties, message);
|
||||
@@ -110,7 +258,7 @@ function issue(name, message = '') {
|
||||
issueCommand(name, {}, message);
|
||||
}
|
||||
exports.issue = issue;
|
||||
const CMD_PREFIX = '##[';
|
||||
const CMD_STRING = '::';
|
||||
class Command {
|
||||
constructor(command, properties, message) {
|
||||
if (!command) {
|
||||
@@ -121,37 +269,42 @@ class Command {
|
||||
this.message = message;
|
||||
}
|
||||
toString() {
|
||||
let cmdStr = CMD_PREFIX + this.command;
|
||||
let cmdStr = CMD_STRING + this.command;
|
||||
if (this.properties && Object.keys(this.properties).length > 0) {
|
||||
cmdStr += ' ';
|
||||
let first = true;
|
||||
for (const key in this.properties) {
|
||||
if (this.properties.hasOwnProperty(key)) {
|
||||
const val = this.properties[key];
|
||||
if (val) {
|
||||
// safely append the val - avoid blowing up when attempting to
|
||||
// call .replace() if message is not a string for some reason
|
||||
cmdStr += `${key}=${escape(`${val || ''}`)};`;
|
||||
if (first) {
|
||||
first = false;
|
||||
}
|
||||
else {
|
||||
cmdStr += ',';
|
||||
}
|
||||
cmdStr += `${key}=${escapeProperty(val)}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cmdStr += ']';
|
||||
// safely append the message - avoid blowing up when attempting to
|
||||
// call .replace() if message is not a string for some reason
|
||||
const message = `${this.message || ''}`;
|
||||
cmdStr += escapeData(message);
|
||||
cmdStr += `${CMD_STRING}${escapeData(this.message)}`;
|
||||
return cmdStr;
|
||||
}
|
||||
}
|
||||
function escapeData(s) {
|
||||
return s.replace(/\r/g, '%0D').replace(/\n/g, '%0A');
|
||||
return utils_1.toCommandValue(s)
|
||||
.replace(/%/g, '%25')
|
||||
.replace(/\r/g, '%0D')
|
||||
.replace(/\n/g, '%0A');
|
||||
}
|
||||
function escape(s) {
|
||||
return s
|
||||
function escapeProperty(s) {
|
||||
return utils_1.toCommandValue(s)
|
||||
.replace(/%/g, '%25')
|
||||
.replace(/\r/g, '%0D')
|
||||
.replace(/\n/g, '%0A')
|
||||
.replace(/]/g, '%5D')
|
||||
.replace(/;/g, '%3B');
|
||||
.replace(/:/g, '%3A')
|
||||
.replace(/,/g, '%2C');
|
||||
}
|
||||
//# sourceMappingURL=command.js.map
|
||||
|
||||
@@ -171,9 +324,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const command_1 = __webpack_require__(431);
|
||||
const path = __webpack_require__(622);
|
||||
const file_command_1 = __webpack_require__(102);
|
||||
const utils_1 = __webpack_require__(82);
|
||||
const os = __importStar(__webpack_require__(87));
|
||||
const path = __importStar(__webpack_require__(622));
|
||||
/**
|
||||
* The code to exit an action
|
||||
*/
|
||||
@@ -192,34 +355,45 @@ var ExitCode;
|
||||
// Variables
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* sets env variable for this action and future actions in the job
|
||||
* Sets env variable for this action and future actions in the job
|
||||
* @param name the name of the variable to set
|
||||
* @param val the value of the variable
|
||||
* @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function exportVariable(name, val) {
|
||||
process.env[name] = val;
|
||||
command_1.issueCommand('set-env', { name }, val);
|
||||
const convertedVal = utils_1.toCommandValue(val);
|
||||
process.env[name] = convertedVal;
|
||||
const filePath = process.env['GITHUB_ENV'] || '';
|
||||
if (filePath) {
|
||||
const delimiter = '_GitHubActionsFileCommandDelimeter_';
|
||||
const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`;
|
||||
file_command_1.issueCommand('ENV', commandValue);
|
||||
}
|
||||
else {
|
||||
command_1.issueCommand('set-env', { name }, convertedVal);
|
||||
}
|
||||
}
|
||||
exports.exportVariable = exportVariable;
|
||||
/**
|
||||
* exports the variable and registers a secret which will get masked from logs
|
||||
* @param name the name of the variable to set
|
||||
* @param val value of the secret
|
||||
* Registers a secret which will get masked from logs
|
||||
* @param secret value of the secret
|
||||
*/
|
||||
function exportSecret(name, val) {
|
||||
exportVariable(name, val);
|
||||
// the runner will error with not implemented
|
||||
// leaving the function but raising the error earlier
|
||||
command_1.issueCommand('set-secret', {}, val);
|
||||
throw new Error('Not implemented.');
|
||||
function setSecret(secret) {
|
||||
command_1.issueCommand('add-mask', {}, secret);
|
||||
}
|
||||
exports.exportSecret = exportSecret;
|
||||
exports.setSecret = setSecret;
|
||||
/**
|
||||
* Prepends inputPath to the PATH (for this action and future actions)
|
||||
* @param inputPath
|
||||
*/
|
||||
function addPath(inputPath) {
|
||||
command_1.issueCommand('add-path', {}, inputPath);
|
||||
const filePath = process.env['GITHUB_PATH'] || '';
|
||||
if (filePath) {
|
||||
file_command_1.issueCommand('PATH', inputPath);
|
||||
}
|
||||
else {
|
||||
command_1.issueCommand('add-path', {}, inputPath);
|
||||
}
|
||||
process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;
|
||||
}
|
||||
exports.addPath = addPath;
|
||||
@@ -231,7 +405,7 @@ exports.addPath = addPath;
|
||||
* @returns string
|
||||
*/
|
||||
function getInput(name, options) {
|
||||
const val = process.env[`INPUT_${name.replace(' ', '_').toUpperCase()}`] || '';
|
||||
const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || '';
|
||||
if (options && options.required && !val) {
|
||||
throw new Error(`Input required and not supplied: ${name}`);
|
||||
}
|
||||
@@ -242,12 +416,22 @@ exports.getInput = getInput;
|
||||
* Sets the value of an output.
|
||||
*
|
||||
* @param name name of the output to set
|
||||
* @param value value to store
|
||||
* @param value value to store. Non-string values will be converted to a string via JSON.stringify
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function setOutput(name, value) {
|
||||
command_1.issueCommand('set-output', { name }, value);
|
||||
}
|
||||
exports.setOutput = setOutput;
|
||||
/**
|
||||
* Enables or disables the echoing of commands into stdout for the rest of the step.
|
||||
* Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.
|
||||
*
|
||||
*/
|
||||
function setCommandEcho(enabled) {
|
||||
command_1.issue('echo', enabled ? 'on' : 'off');
|
||||
}
|
||||
exports.setCommandEcho = setCommandEcho;
|
||||
//-----------------------------------------------------------------------
|
||||
// Results
|
||||
//-----------------------------------------------------------------------
|
||||
@@ -264,6 +448,13 @@ exports.setFailed = setFailed;
|
||||
//-----------------------------------------------------------------------
|
||||
// Logging Commands
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Gets whether Actions Step Debug is on or not
|
||||
*/
|
||||
function isDebug() {
|
||||
return process.env['RUNNER_DEBUG'] === '1';
|
||||
}
|
||||
exports.isDebug = isDebug;
|
||||
/**
|
||||
* Writes debug message to user log
|
||||
* @param message debug message
|
||||
@@ -274,20 +465,28 @@ function debug(message) {
|
||||
exports.debug = debug;
|
||||
/**
|
||||
* Adds an error issue
|
||||
* @param message error issue message
|
||||
* @param message error issue message. Errors will be converted to string via toString()
|
||||
*/
|
||||
function error(message) {
|
||||
command_1.issue('error', message);
|
||||
command_1.issue('error', message instanceof Error ? message.toString() : message);
|
||||
}
|
||||
exports.error = error;
|
||||
/**
|
||||
* Adds an warning issue
|
||||
* @param message warning issue message
|
||||
* @param message warning issue message. Errors will be converted to string via toString()
|
||||
*/
|
||||
function warning(message) {
|
||||
command_1.issue('warning', message);
|
||||
command_1.issue('warning', message instanceof Error ? message.toString() : message);
|
||||
}
|
||||
exports.warning = warning;
|
||||
/**
|
||||
* Writes info to log with console.log.
|
||||
* @param message info message
|
||||
*/
|
||||
function info(message) {
|
||||
process.stdout.write(message + os.EOL);
|
||||
}
|
||||
exports.info = info;
|
||||
/**
|
||||
* Begin an output group.
|
||||
*
|
||||
@@ -328,6 +527,30 @@ function group(name, fn) {
|
||||
});
|
||||
}
|
||||
exports.group = group;
|
||||
//-----------------------------------------------------------------------
|
||||
// Wrapper action state
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Saves state for current action, the state can only be retrieved by this action's post job execution.
|
||||
*
|
||||
* @param name name of the state to store
|
||||
* @param value value to store. Non-string values will be converted to a string via JSON.stringify
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function saveState(name, value) {
|
||||
command_1.issueCommand('save-state', { name }, value);
|
||||
}
|
||||
exports.saveState = saveState;
|
||||
/**
|
||||
* Gets the value of an state set by this action's main execution.
|
||||
*
|
||||
* @param name name of the state to get
|
||||
* @returns string
|
||||
*/
|
||||
function getState(name) {
|
||||
return process.env[`STATE_${name}`] || '';
|
||||
}
|
||||
exports.getState = getState;
|
||||
//# sourceMappingURL=core.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
85
index.js
85
index.js
@@ -1,20 +1,91 @@
|
||||
const core = require('@actions/core');
|
||||
const child_process = require('child_process');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const crypto = require('crypto');
|
||||
|
||||
try {
|
||||
console.log("Adding GitHub.com keys to /home/runner/ssh_known_hosts");
|
||||
fs.mkdirSync('/home/runner/.ssh', { recursive: true});
|
||||
fs.appendFileSync('/home/runner/.ssh/known_hosts', '\ngithub.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==\n');
|
||||
fs.appendFileSync('/home/runner/.ssh/known_hosts', '\ngithub.com ssh-dss AAAAB3NzaC1kc3MAAACBANGFW2P9xlGU3zWrymJgI/lKo//ZW2WfVtmbsUZJ5uyKArtlQOT2+WRhcg4979aFxgKdcsqAYW3/LS1T2km3jYW/vr4Uzn+dXWODVk5VlUiZ1HFOHf6s6ITcZvjvdbp6ZbpM+DuJT7Bw+h5Fx8Qt8I16oCZYmAPJRtu46o9C2zk1AAAAFQC4gdFGcSbp5Gr0Wd5Ay/jtcldMewAAAIATTgn4sY4Nem/FQE+XJlyUQptPWMem5fwOcWtSXiTKaaN0lkk2p2snz+EJvAGXGq9dTSWHyLJSM2W6ZdQDqWJ1k+cL8CARAqL+UMwF84CR0m3hj+wtVGD/J4G5kW2DBAf4/bqzP4469lT+dF2FRQ2L9JKXrCWcnhMtJUvua8dvnwAAAIB6C4nQfAA7x8oLta6tT+oCk2WQcydNsyugE8vLrHlogoWEicla6cWPk7oXSspbzUcfkjN3Qa6e74PhRkc7JdSdAlFzU3m7LMkXo1MHgkqNX8glxWNVqBSc0YRdbFdTkL0C6gtpklilhvuHQCdbgB3LBAikcRkDp+FCVkUgPC/7Rw==\n');
|
||||
const privateKey = core.getInput('ssh-private-key');
|
||||
|
||||
if (!privateKey) {
|
||||
core.setFailed("The ssh-private-key argument is empty. Maybe the secret has not been configured, or you are using a wrong secret name in your workflow file.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var home;
|
||||
|
||||
if (process.env['OS'] == 'Windows_NT') {
|
||||
console.log('Preparing ssh-agent service on Windows');
|
||||
child_process.execSync('sc config ssh-agent start=demand', { stdio: 'inherit' });
|
||||
|
||||
home = os.homedir();
|
||||
} else {
|
||||
// Use getent() system call, since this is what ssh does; makes a difference in Docker-based
|
||||
// Action runs, where $HOME is different from the pwent
|
||||
var { homedir: home } = os.userInfo();
|
||||
}
|
||||
|
||||
const homeSsh = home + '/.ssh';
|
||||
|
||||
console.log(`Adding GitHub.com keys to ${homeSsh}/known_hosts`);
|
||||
fs.mkdirSync(homeSsh, { recursive: true });
|
||||
fs.appendFileSync(`${homeSsh}/known_hosts`, '\ngithub.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==\n');
|
||||
fs.appendFileSync(`${homeSsh}/known_hosts`, '\ngithub.com ssh-dss AAAAB3NzaC1kc3MAAACBANGFW2P9xlGU3zWrymJgI/lKo//ZW2WfVtmbsUZJ5uyKArtlQOT2+WRhcg4979aFxgKdcsqAYW3/LS1T2km3jYW/vr4Uzn+dXWODVk5VlUiZ1HFOHf6s6ITcZvjvdbp6ZbpM+DuJT7Bw+h5Fx8Qt8I16oCZYmAPJRtu46o9C2zk1AAAAFQC4gdFGcSbp5Gr0Wd5Ay/jtcldMewAAAIATTgn4sY4Nem/FQE+XJlyUQptPWMem5fwOcWtSXiTKaaN0lkk2p2snz+EJvAGXGq9dTSWHyLJSM2W6ZdQDqWJ1k+cL8CARAqL+UMwF84CR0m3hj+wtVGD/J4G5kW2DBAf4/bqzP4469lT+dF2FRQ2L9JKXrCWcnhMtJUvua8dvnwAAAIB6C4nQfAA7x8oLta6tT+oCk2WQcydNsyugE8vLrHlogoWEicla6cWPk7oXSspbzUcfkjN3Qa6e74PhRkc7JdSdAlFzU3m7LMkXo1MHgkqNX8glxWNVqBSc0YRdbFdTkL0C6gtpklilhvuHQCdbgB3LBAikcRkDp+FCVkUgPC/7Rw==\n');
|
||||
|
||||
console.log("Starting ssh-agent");
|
||||
const authSock = core.getInput('ssh-auth-sock');
|
||||
child_process.execFileSync('ssh-agent', ['-a', authSock]);
|
||||
core.exportVariable('SSH_AUTH_SOCK', authSock);
|
||||
let sshAgentOutput = ''
|
||||
if (authSock && authSock.length > 0) {
|
||||
sshAgentOutput = child_process.execFileSync('ssh-agent', ['-a', authSock]);
|
||||
} else {
|
||||
sshAgentOutput = child_process.execFileSync('ssh-agent')
|
||||
}
|
||||
|
||||
// Extract auth socket path and agent pid and set them as job variables
|
||||
const lines = sshAgentOutput.toString().split("\n")
|
||||
for (const lineNumber in lines) {
|
||||
const matches = /^(SSH_AUTH_SOCK|SSH_AGENT_PID)=(.*); export \1/.exec(lines[lineNumber])
|
||||
if (matches && matches.length > 0) {
|
||||
core.exportVariable(matches[1], matches[2])
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Adding private key to agent");
|
||||
child_process.execSync('ssh-add -', { input: core.getInput('ssh-private-key') });
|
||||
privateKey.split(/(?=-----BEGIN)/).forEach(function(key) {
|
||||
child_process.execSync('ssh-add -', { input: key.trim() + "\n" });
|
||||
});
|
||||
|
||||
console.log("Keys added:");
|
||||
child_process.execSync('ssh-add -l', { stdio: 'inherit' });
|
||||
|
||||
child_process.execFileSync('ssh-add', ['-L']).toString().split(/\r?\n/).forEach(function(key) {
|
||||
let parts = key.match(/\bgithub.com[:/](.*)(?:\.git)?\b/);
|
||||
|
||||
if (parts == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
let ownerAndRepo = parts[1];
|
||||
let sha256 = crypto.createHash('sha256').update(key).digest('hex');
|
||||
|
||||
fs.writeFileSync(`${homeSsh}/${sha256}`, key + "\n", { mode: '600' });
|
||||
|
||||
child_process.execSync(`git config --global --replace-all url."git@${sha256}:${ownerAndRepo}".insteadOf "https://github.com/${ownerAndRepo}"`);
|
||||
child_process.execSync(`git config --global --add url."git@${sha256}:${ownerAndRepo}".insteadOf "git@github.com:${ownerAndRepo}"`);
|
||||
child_process.execSync(`git config --global --add url."git@${sha256}:${ownerAndRepo}".insteadOf "ssh://git@github.com/${ownerAndRepo}"`);
|
||||
|
||||
let sshConfig = `\nHost ${sha256}\n`
|
||||
+ ` HostName github.com\n`
|
||||
+ ` User git\n`
|
||||
+ ` IdentityFile ${homeSsh}/${sha256}\n`
|
||||
+ ` IdentitiesOnly yes\n`;
|
||||
|
||||
fs.appendFileSync(`${homeSsh}/config`, sshConfig);
|
||||
|
||||
console.log(`Added deploy-key mapping: Use key "${key}" for GitHub repository ${ownerAndRepo}`);
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
core.setFailed(error.message);
|
||||
}
|
||||
|
||||
26
package-lock.json
generated
26
package-lock.json
generated
@@ -1,26 +0,0 @@
|
||||
{
|
||||
"name": "webfactory-action-ssh-agent",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@actions/core": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.1.0.tgz",
|
||||
"integrity": "sha512-KKpo3xzo0Zsikni9tbOsEQkxZBGDsYSJZNkTvmo0gPSXrc98TBOcdTvKwwjitjkjHkreTggWdB1ACiAFVgsuzA==",
|
||||
"dev": true
|
||||
},
|
||||
"@zeit/ncc": {
|
||||
"version": "0.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@zeit/ncc/-/ncc-0.20.5.tgz",
|
||||
"integrity": "sha512-XU6uzwvv95DqxciQx+aOLhbyBx/13ky+RK1y88Age9Du3BlA4mMPCy13BGjayOrrumOzlq1XV3SD/BWiZENXlw==",
|
||||
"dev": true
|
||||
},
|
||||
"child_process": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz",
|
||||
"integrity": "sha1-sffn/HPSXn/R1FWtyU4UODAYK1o=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,10 @@
|
||||
"author": "webfactory GmbH <info@webfactory.de>",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@actions/core": "^1.1.0",
|
||||
"@zeit/ncc": "^0.20.5",
|
||||
"child_process": "^1.0.2"
|
||||
"@actions/core": "^1.2.4",
|
||||
"@zeit/ncc": "^0.20.5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "node scripts/build.js"
|
||||
}
|
||||
}
|
||||
|
||||
41
scripts/build.js
Normal file
41
scripts/build.js
Normal file
@@ -0,0 +1,41 @@
|
||||
const { execSync } = require('child_process')
|
||||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
const process = require('process')
|
||||
|
||||
const buildDir = path.join(process.cwd(), 'build')
|
||||
const distDir = path.join(process.cwd(), 'dist')
|
||||
|
||||
const buildIndexJs = path.join(buildDir, 'index.js')
|
||||
const distIndexJs = path.join(distDir, 'index.js')
|
||||
const distCleanupJs = path.join(distDir, 'cleanup.js')
|
||||
|
||||
var ncc = `./node_modules/.bin/ncc`;
|
||||
if (process.platform === "win32") {
|
||||
ncc = `.\\node_modules\\.bin\\ncc.cmd`;
|
||||
}
|
||||
|
||||
if (!fs.existsSync(buildDir)) {
|
||||
fs.mkdirSync(buildDir)
|
||||
}
|
||||
|
||||
// Build the main index.js file
|
||||
console.log('Building index.js...')
|
||||
execSync(`${ncc} build index.js -q -o ${buildDir}`)
|
||||
if (fs.existsSync(distIndexJs)) {
|
||||
fs.unlinkSync(distIndexJs)
|
||||
}
|
||||
fs.renameSync(buildIndexJs, distIndexJs)
|
||||
|
||||
// Build the cleanup.js file
|
||||
console.log('Building cleanup.js...')
|
||||
execSync(`${ncc} build cleanup.js -q -o ${buildDir}`)
|
||||
if (fs.existsSync(distCleanupJs)) {
|
||||
fs.unlinkSync(distCleanupJs)
|
||||
}
|
||||
fs.renameSync(buildIndexJs, distCleanupJs)
|
||||
|
||||
console.log('Cleaning up...')
|
||||
fs.rmdirSync(buildDir)
|
||||
|
||||
console.log('Done')
|
||||
13
yarn.lock
Normal file
13
yarn.lock
Normal file
@@ -0,0 +1,13 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@actions/core@^1.2.4":
|
||||
version "1.2.6"
|
||||
resolved "https://registry.yarnpkg.com/@actions/core/-/core-1.2.6.tgz#a78d49f41a4def18e88ce47c2cac615d5694bf09"
|
||||
integrity sha512-ZQYitnqiyBc3D+k7LsgSBmMDVkOVidaagDG7j3fOym77jNunWRuYx7VSHa9GNfFZh+zh61xsCjRj4JxMZlDqTA==
|
||||
|
||||
"@zeit/ncc@^0.20.5":
|
||||
version "0.20.5"
|
||||
resolved "https://registry.yarnpkg.com/@zeit/ncc/-/ncc-0.20.5.tgz#a41af6e6bcab4a58f4612bae6137f70bce0192e3"
|
||||
integrity sha512-XU6uzwvv95DqxciQx+aOLhbyBx/13ky+RK1y88Age9Du3BlA4mMPCy13BGjayOrrumOzlq1XV3SD/BWiZENXlw==
|
||||
Reference in New Issue
Block a user