mirror of
https://github.com/webfactory/ssh-agent.git
synced 2026-03-19 17:49:06 +08:00
Compare commits
55 Commits
demo-go-ge
...
debug-wind
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d8d48e56a | ||
|
|
5a354bf325 | ||
|
|
6458b79183 | ||
|
|
873b13078f | ||
|
|
3fc2400425 | ||
|
|
3715bc571d | ||
|
|
71155bedbe | ||
|
|
10fed90131 | ||
|
|
d3770df27e | ||
|
|
7667967a0a | ||
|
|
c77dd5afd7 | ||
|
|
a4b2891e37 | ||
|
|
7cabdfc0cc | ||
|
|
da67187c5e | ||
|
|
64510141b4 | ||
|
|
8cdc63104f | ||
|
|
e0d767fd8e | ||
|
|
feedd601c5 | ||
|
|
e35dbcbae9 | ||
|
|
cbf6c2b3c2 | ||
|
|
2bcaae34da | ||
|
|
f03f6e3358 | ||
|
|
7d6e731f4a | ||
|
|
88bcf9af86 | ||
|
|
02a6899abb | ||
|
|
5f971b8d4f | ||
|
|
ab7e1e8f32 | ||
|
|
7f61bbc4ae | ||
|
|
2bde568a83 | ||
|
|
93c9b23aa1 | ||
|
|
1606d19f15 | ||
|
|
8addcca750 | ||
|
|
166067472e | ||
|
|
f78cad1cc7 | ||
|
|
ccd95b931d | ||
|
|
637f9c791e | ||
|
|
18f53866de | ||
|
|
c91aeeb123 | ||
|
|
25b1b5d69f | ||
|
|
9406a51fa5 | ||
|
|
ef63fdb1df | ||
|
|
7fc4d80a06 | ||
|
|
9b7e80db62 | ||
|
|
4d491fcb08 | ||
|
|
1676d1f2a9 | ||
|
|
3702096734 | ||
|
|
253819f283 | ||
|
|
231e859720 | ||
|
|
5e4ad4bcc8 | ||
|
|
c56b9c4c81 | ||
|
|
d7353c1718 | ||
|
|
bcd9c12595 | ||
|
|
ab4471f51e | ||
|
|
05624726bc | ||
|
|
2a421d8dab |
74
.github/workflows/demo.yml
vendored
74
.github/workflows/demo.yml
vendored
@@ -1,47 +1,45 @@
|
|||||||
on: [ push, pull_request ]
|
on: [push, pull_request]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deployment_keys_demo:
|
deployment_keys_demo:
|
||||||
|
env:
|
||||||
|
GIT_SSH_COMMAND: ssh -v
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ ubuntu-latest, macOS-latest, windows-latest ]
|
os: [windows-latest]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Setup key
|
# - name: Setup key
|
||||||
uses: ./
|
# uses: ./
|
||||||
with:
|
# with:
|
||||||
ssh-private-key: |
|
# ssh-private-key: |
|
||||||
${{ secrets.MPDUDE_TEST_1_DEPLOY_KEY }}
|
# ${{ secrets.MPDUDE_TEST_1_DEPLOY_KEY }}
|
||||||
${{ secrets.MPDUDE_TEST_2_DEPLOY_KEY }}
|
# ${{ secrets.MPDUDE_TEST_2_DEPLOY_KEY }}
|
||||||
- run: |
|
# - run: |
|
||||||
git clone https://github.com/mpdude/test-1.git test-1-http
|
# cat ~/.ssh/config
|
||||||
git clone git@github.com:mpdude/test-1.git test-1-git
|
# ssh-add -l
|
||||||
git clone ssh://git@github.com/mpdude/test-1.git test-1-git-ssh
|
# C:/Windows/System32/OpenSSH/ssh.exe -v git@key-2 'echo octocat'
|
||||||
git clone https://github.com/mpdude/test-2.git test-2-http
|
- name: Start SSH session
|
||||||
git clone git@github.com:mpdude/test-2.git test-2-git
|
uses: luchihoratiu/debug-via-ssh@main
|
||||||
git clone ssh://git@github.com/mpdude/test-2.git test-2-git-ssh
|
with:
|
||||||
go get -v github.com/mpdude/test-2
|
NGROK_AUTH_TOKEN: ${{ secrets.NGROK_AUTH_TOKEN }}
|
||||||
|
SSH_PASS: ${{ secrets.SSH_PASS }}
|
||||||
docker_demo:
|
|
||||||
runs-on: ubuntu-latest
|
# git clone git@github.com:mpdude/test-2.git test-2-git
|
||||||
container:
|
# ls -alh ~/.ssh
|
||||||
image: ubuntu:latest
|
# git clone https://github.com/mpdude/test-1.git test-1-http
|
||||||
steps:
|
# git clone git@github.com:mpdude/test-1.git test-1-git
|
||||||
- uses: actions/checkout@v2
|
# git clone ssh://git@github.com/mpdude/test-1.git test-1-git-ssh
|
||||||
- run: apt update && apt install -y openssh-client git
|
# git clone https://github.com/mpdude/test-2.git test-2-http
|
||||||
- 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
|
|
||||||
|
|
||||||
|
# git clone ssh://git@github.com/mpdude/test-2.git test-2-git-ssh
|
||||||
|
|
||||||
|
# cat > ~/.ssh/5965bf89ab6e2900262e3f6802dfb4d65cb0de539d0fbb97d381e7130a4ba7e9 <<< "${{ secrets.MPDUDE_TEST_2_DEPLOY_KEY }}"
|
||||||
|
# ssh-keygen -p -f ~/.ssh/5965bf89ab6e2900262e3f6802dfb4d65cb0de539d0fbb97d381e7130a4ba7e9 -N secret-passphrase
|
||||||
|
# eval `ssh-agent`
|
||||||
|
# echo "secret-passphrase" | ssh-add ~/.ssh/5965bf89ab6e2900262e3f6802dfb4d65cb0de539d0fbb97d381e7130a4ba7e9
|
||||||
|
# ssh-add -L
|
||||||
|
# git clone git@github.com:mpdude/test-2.git test-2-git
|
||||||
|
# shell: bash
|
||||||
|
|||||||
48
README.md
48
README.md
@@ -33,9 +33,9 @@ jobs:
|
|||||||
...
|
...
|
||||||
steps:
|
steps:
|
||||||
- actions/checkout@v2
|
- actions/checkout@v2
|
||||||
# Make sure the @v0.5.3 matches the current version of the
|
# Make sure the @v0.5.0 matches the current version of the
|
||||||
# action
|
# action
|
||||||
- uses: webfactory/ssh-agent@v0.5.3
|
- uses: webfactory/ssh-agent@v0.5.0
|
||||||
with:
|
with:
|
||||||
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
|
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||||
- ... other steps
|
- ... other steps
|
||||||
@@ -50,7 +50,7 @@ You can set up different keys as different secrets and pass them all to the acti
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# ... contens as before
|
# ... contens as before
|
||||||
- uses: webfactory/ssh-agent@v0.5.3
|
- uses: webfactory/ssh-agent@v0.5.0
|
||||||
with:
|
with:
|
||||||
ssh-private-key: |
|
ssh-private-key: |
|
||||||
${{ secrets.FIRST_KEY }}
|
${{ secrets.FIRST_KEY }}
|
||||||
@@ -68,7 +68,7 @@ When using **Github deploy keys**, GitHub servers will accept the _first_ known
|
|||||||
|
|
||||||
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.
|
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. (Hint: Try `ssh-keygen ... -C "git@github.com:owner/repo.git"`.)
|
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.
|
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`.
|
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.
|
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.
|
||||||
@@ -90,46 +90,6 @@ If the private key is not in the `PEM` format, you will see an `Error loading ke
|
|||||||
|
|
||||||
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 😉.
|
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 😉.
|
||||||
|
|
||||||
## Additional Information for Particular Tools or Platforms
|
|
||||||
|
|
||||||
If you know that your favorite tool or platform of choice requires extra tweaks or has some caveats when running with SSH, feel free to open a PR to amend this section here.
|
|
||||||
|
|
||||||
### Container-based Workflows
|
|
||||||
|
|
||||||
If you are using this action on container-based workflows, make sure the container has the necessary SSH binaries or package(s) installed.
|
|
||||||
|
|
||||||
### Cargo's (Rust) Private Dependencies on Windows
|
|
||||||
|
|
||||||
If you are using private repositories in your dependencies like this:
|
|
||||||
|
|
||||||
```
|
|
||||||
stuff = { git = "ssh://git@github.com/myorg/stuff.git", branch = "main" }
|
|
||||||
```
|
|
||||||
|
|
||||||
... you will need to change a configuration in the workflow for Windows machines in order to make cargo able to clone private repositories.
|
|
||||||
|
|
||||||
There are 2 ways you can achieve this:
|
|
||||||
|
|
||||||
1. Add this step once in your job **before** any cargo command:
|
|
||||||
|
|
||||||
```
|
|
||||||
- name: Update cargo config to use Git CLI
|
|
||||||
run: Set-Content -Path $env:USERPROFILE\.cargo\config.toml "[net]`ngit-fetch-with-cli = true"
|
|
||||||
```
|
|
||||||
|
|
||||||
This will configure Cargo to use the Git CLI as explained in the [Cargo's documentation](https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli).
|
|
||||||
|
|
||||||
2. Alternatively you can set it to the environment variables for the entire workflow:
|
|
||||||
|
|
||||||
```
|
|
||||||
env:
|
|
||||||
CARGO_NET_GIT_FETCH_WITH_CLI: true
|
|
||||||
```
|
|
||||||
|
|
||||||
### Using Deploy Keys with Swift Package Manager
|
|
||||||
|
|
||||||
`xcodebuild` by default uses Xcode's built-in Git tooling. If you want to use GitHub Deploy Keys as supported by this action, however, that version of Git will lack the necessary URL remapping. In this case, pass `-scmProvider system` to the `xcodebuild` command, as mentioned in [Apple's documentation](https://developer.apple.com/documentation/swift_packages/building_swift_packages_or_apps_that_use_them_in_continuous_integration_workflows#3680255).
|
|
||||||
|
|
||||||
## What this Action *cannot* do for you
|
## What this Action *cannot* do for you
|
||||||
|
|
||||||
The following items are not issues, but beyond what this Action is supposed to do.
|
The following items are not issues, but beyond what this Action is supposed to do.
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ runs:
|
|||||||
using: 'node12'
|
using: 'node12'
|
||||||
main: 'dist/index.js'
|
main: 'dist/index.js'
|
||||||
post: 'dist/cleanup.js'
|
post: 'dist/cleanup.js'
|
||||||
post-if: 'always()'
|
|
||||||
branding:
|
branding:
|
||||||
icon: loader
|
icon: loader
|
||||||
color: 'yellow'
|
color: 'yellow'
|
||||||
|
|||||||
24
askpass.c
Normal file
24
askpass.c
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
ssh-add on Windows (probably part of the source at https://github.com/PowerShell/openssh-portable)
|
||||||
|
does not/can not read the passphrase from stdin.
|
||||||
|
|
||||||
|
However, when the DISPLAY env var is set and ssh-add is not run from a terminal (however it tests
|
||||||
|
that), it will run the executable pointed to by SSH_ASKPASS in a subprocess and read the passphrase
|
||||||
|
from that subprocess' stdout.
|
||||||
|
|
||||||
|
This program can be used as the SSH_ASKPASS implementation. It will return the passphrase set
|
||||||
|
in the SSH_PASS env variable.
|
||||||
|
|
||||||
|
To cross-compile from Ubuntu, I installed the `mingw-w64` package and ran
|
||||||
|
$ x86_64-w64-mingw32-gcc askpass.c -static -o askpass.exe
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
printf("%s\n", getenv("SSH_PASS"));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
askpass.exe
Executable file
BIN
askpass.exe
Executable file
Binary file not shown.
@@ -1,11 +1,10 @@
|
|||||||
const core = require('@actions/core');
|
const core = require('@actions/core')
|
||||||
const { execFileSync } = require('child_process');
|
const { execSync } = require('child_process')
|
||||||
const { sshAgent } = require('./paths.js');
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Kill the started SSH agent
|
// Kill the started SSH agent
|
||||||
console.log('Stopping SSH agent');
|
console.log('Stopping SSH agent')
|
||||||
execFileSync(sshAgent, ['-k'], { stdio: 'inherit' });
|
execSync('kill ${SSH_AGENT_PID}', { stdio: 'inherit' })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error.message);
|
console.log(error.message);
|
||||||
console.log('Error stopping the SSH agent, proceeding anyway');
|
console.log('Error stopping the SSH agent, proceeding anyway');
|
||||||
|
|||||||
34
dist/cleanup.js
vendored
34
dist/cleanup.js
vendored
@@ -122,14 +122,13 @@ module.exports = require("child_process");
|
|||||||
/***/ 175:
|
/***/ 175:
|
||||||
/***/ (function(__unusedmodule, __unusedexports, __webpack_require__) {
|
/***/ (function(__unusedmodule, __unusedexports, __webpack_require__) {
|
||||||
|
|
||||||
const core = __webpack_require__(470);
|
const core = __webpack_require__(470)
|
||||||
const { execFileSync } = __webpack_require__(129);
|
const { execSync } = __webpack_require__(129)
|
||||||
const { sshAgent } = __webpack_require__(972);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Kill the started SSH agent
|
// Kill the started SSH agent
|
||||||
console.log('Stopping SSH agent');
|
console.log('Stopping SSH agent')
|
||||||
execFileSync(sshAgent, ['-k'], { stdio: 'inherit' });
|
execSync('kill ${SSH_AGENT_PID}', { stdio: 'inherit' })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error.message);
|
console.log(error.message);
|
||||||
console.log('Error stopping the SSH agent, proceeding anyway');
|
console.log('Error stopping the SSH agent, proceeding anyway');
|
||||||
@@ -481,31 +480,6 @@ module.exports = require("path");
|
|||||||
|
|
||||||
module.exports = require("fs");
|
module.exports = require("fs");
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 972:
|
|
||||||
/***/ (function(module, __unusedexports, __webpack_require__) {
|
|
||||||
|
|
||||||
const os = __webpack_require__(87);
|
|
||||||
|
|
||||||
module.exports = (process.env['OS'] != 'Windows_NT') ? {
|
|
||||||
|
|
||||||
// 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
|
|
||||||
home: os.userInfo().homedir,
|
|
||||||
sshAgent: 'ssh-agent',
|
|
||||||
sshAdd: 'ssh-add'
|
|
||||||
|
|
||||||
} : {
|
|
||||||
|
|
||||||
home: os.homedir(),
|
|
||||||
sshAgent: 'c://progra~1//git//usr//bin//ssh-agent.exe',
|
|
||||||
sshAdd: 'c://progra~1//git//usr//bin//ssh-add.exe'
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***/ })
|
/***/ })
|
||||||
|
|
||||||
/******/ });
|
/******/ });
|
||||||
186
dist/index.js
vendored
186
dist/index.js
vendored
@@ -118,8 +118,9 @@ exports.issueCommand = issueCommand;
|
|||||||
const core = __webpack_require__(470);
|
const core = __webpack_require__(470);
|
||||||
const child_process = __webpack_require__(129);
|
const child_process = __webpack_require__(129);
|
||||||
const fs = __webpack_require__(747);
|
const fs = __webpack_require__(747);
|
||||||
const crypto = __webpack_require__(417);
|
const os = __webpack_require__(87);
|
||||||
const { home, sshAgent, sshAdd } = __webpack_require__(972);
|
const token = __webpack_require__(417).randomBytes(64).toString('hex');
|
||||||
|
const isWindows = (process.env['OS'] == 'Windows_NT');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const privateKey = core.getInput('ssh-private-key');
|
const privateKey = core.getInput('ssh-private-key');
|
||||||
@@ -130,77 +131,113 @@ try {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var home;
|
||||||
|
|
||||||
|
if (isWindows) {
|
||||||
|
console.log('Preparing ssh-agent service on Windows');
|
||||||
|
child_process.execSync('sc config ssh-agent start=demand', { stdio: 'inherit' });
|
||||||
|
|
||||||
|
// Work around https://github.com/PowerShell/openssh-portable/pull/447 by creating a \dev\tty file
|
||||||
|
/*fs.mkdirSync('c:\\dev');
|
||||||
|
fs.closeSync(fs.openSync('c:\\dev\\tty', 'a'));
|
||||||
|
fs.mkdirSync('d:\\dev');
|
||||||
|
fs.closeSync(fs.openSync('d:\\dev\\tty', 'a'));*/
|
||||||
|
|
||||||
|
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';
|
const homeSsh = home + '/.ssh';
|
||||||
|
|
||||||
console.log(`Adding GitHub.com keys to ${homeSsh}/known_hosts`);
|
console.log(`Adding GitHub.com keys to ${homeSsh}/known_hosts`);
|
||||||
|
|
||||||
fs.mkdirSync(homeSsh, { recursive: true });
|
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-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');
|
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");
|
console.log("Starting ssh-agent");
|
||||||
|
|
||||||
const authSock = core.getInput('ssh-auth-sock');
|
const authSock = core.getInput('ssh-auth-sock');
|
||||||
const sshAgentArgs = (authSock && authSock.length > 0) ? ['-a', authSock] : [];
|
let sshAgentOutput = ''
|
||||||
|
if (authSock && authSock.length > 0) {
|
||||||
// Extract auth socket path and agent pid and set them as job variables
|
sshAgentOutput = child_process.execFileSync('ssh-agent', ['-a', authSock]);
|
||||||
child_process.execFileSync(sshAgent, sshAgentArgs).toString().split("\n").forEach(function(line) {
|
} else {
|
||||||
const matches = /^(SSH_AUTH_SOCK|SSH_AGENT_PID)=(.*); export \1/.exec(line);
|
sshAgentOutput = child_process.execFileSync('ssh-agent')
|
||||||
|
|
||||||
if (matches && matches.length > 0) {
|
|
||||||
// This will also set process.env accordingly, so changes take effect for this script
|
|
||||||
core.exportVariable(matches[1], matches[2])
|
|
||||||
console.log(`${matches[1]}=${matches[2]}`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("Adding private key(s) to agent");
|
|
||||||
|
|
||||||
privateKey.split(/(?=-----BEGIN)/).forEach(function(key) {
|
|
||||||
child_process.execFileSync(sshAdd, ['-'], { input: key.trim() + "\n" });
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("Key(s) added:");
|
|
||||||
|
|
||||||
child_process.execFileSync(sshAdd, ['-l'], { stdio: 'inherit' });
|
|
||||||
|
|
||||||
console.log('Configuring deployment key(s)');
|
|
||||||
|
|
||||||
child_process.execFileSync(sshAdd, ['-L']).toString().split(/\r?\n/).forEach(function(key) {
|
|
||||||
const parts = key.match(/\bgithub\.com[:/]([_.a-z0-9-]+\/[_.a-z0-9-]+)/i);
|
|
||||||
|
|
||||||
if (!parts) {
|
|
||||||
console.log(`Comment for key '${key}' does not match GitHub URL pattern. Not treating it as a GitHub deploy key.`);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const sha256 = crypto.createHash('sha256').update(key).digest('hex');
|
|
||||||
const ownerAndRepo = parts[1].replace(/\.git$/, '');
|
|
||||||
|
|
||||||
fs.writeFileSync(`${homeSsh}/key-${sha256}`, key + "\n", { mode: '600' });
|
|
||||||
|
|
||||||
child_process.execSync(`git config --global --replace-all url."git@key-${sha256}.github.com:${ownerAndRepo}".insteadOf "https://github.com/${ownerAndRepo}"`);
|
|
||||||
child_process.execSync(`git config --global --add url."git@key-${sha256}.github.com:${ownerAndRepo}".insteadOf "git@github.com:${ownerAndRepo}"`);
|
|
||||||
child_process.execSync(`git config --global --add url."git@key-${sha256}.github.com:${ownerAndRepo}".insteadOf "ssh://git@github.com/${ownerAndRepo}"`);
|
|
||||||
|
|
||||||
const sshConfig = `\nHost key-${sha256}.github.com\n`
|
|
||||||
+ ` HostName github.com\n`
|
|
||||||
+ ` IdentityFile ${homeSsh}/key-${sha256}\n`
|
|
||||||
+ ` IdentitiesOnly yes\n`;
|
|
||||||
|
|
||||||
fs.appendFileSync(`${homeSsh}/config`, sshConfig);
|
|
||||||
|
|
||||||
console.log(`Added deploy-key mapping: Use identity '${homeSsh}/key-${sha256}' for GitHub repository ${ownerAndRepo}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
|
|
||||||
if (error.code == 'ENOENT') {
|
|
||||||
console.log(`The '${error.path}' executable could not be found. Please make sure it is on your PATH and/or the necessary packages are installed.`);
|
|
||||||
console.log(`PATH is set to: ${process.env.PATH}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 keys to agent");
|
||||||
|
var keyNumber = 0;
|
||||||
|
|
||||||
|
privateKey.split(/(?=-----BEGIN)/).forEach(function(key) {
|
||||||
|
++keyNumber;
|
||||||
|
let keyFile = `${homeSsh}/key_${keyNumber}`;
|
||||||
|
|
||||||
|
// Write private key (unencrypted!) to file
|
||||||
|
console.log(`Write file ${keyFile}`);
|
||||||
|
fs.writeFileSync(keyFile, key.replace("\r\n", "\n").trim() + "\n", { mode: '600' });
|
||||||
|
|
||||||
|
// Set private key passphrase
|
||||||
|
let output = '';
|
||||||
|
try {
|
||||||
|
console.log(`Set passphrase on ${keyFile}`);
|
||||||
|
output = child_process.execFileSync('ssh-keygen', ['-p', '-f', keyFile, '-N', token]);
|
||||||
|
} catch (exception) {
|
||||||
|
fs.unlinkSync(keyFile);
|
||||||
|
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load key into agent
|
||||||
|
if (isWindows) {
|
||||||
|
child_process.execFileSync('ssh-add', [keyFile], { env: { ...process.env, ...{ 'DISPLAY': 'fake', 'SSH_PASS': token, 'SSH_ASKPASS': 'D:\\a\\ssh-agent\\ssh-agent\\askpass.exe' } } });
|
||||||
|
} else {
|
||||||
|
child_process.execFileSync('ssh-add', [keyFile], { env: process.env, input: token });
|
||||||
|
}
|
||||||
|
|
||||||
|
output.toString().split(/\r?\n/).forEach(function(key) {
|
||||||
|
let parts = key.match(/^Key has comment '.*\bgithub\.com[:/]([_.a-z0-9-]+\/[_.a-z0-9-]+?)(?=\.git|\s|\')/);
|
||||||
|
|
||||||
|
if (parts == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let ownerAndRepo = parts[1];
|
||||||
|
|
||||||
|
child_process.execSync(`git config --global --replace-all url."git@key-${keyNumber}:${ownerAndRepo}".insteadOf "https://github.com/${ownerAndRepo}"`);
|
||||||
|
child_process.execSync(`git config --global --add url."git@key-${keyNumber}:${ownerAndRepo}".insteadOf "git@github.com:${ownerAndRepo}"`);
|
||||||
|
child_process.execSync(`git config --global --add url."git@key-${keyNumber}:${ownerAndRepo}".insteadOf "ssh://git@github.com/${ownerAndRepo}"`);
|
||||||
|
|
||||||
|
// On Linux and OS X, IdentitiesOnly=no will send all keys from agent before the explicit key, so use "yes".
|
||||||
|
// On Windows, IdentitiesOnly=yes will ignore keys from the agent, but send explicit keys first; so use "no" (https://github.com/PowerShell/Win32-OpenSSH/issues/1550)
|
||||||
|
//let identitiesOnly = isWindows ? 'no' : 'yes';
|
||||||
|
|
||||||
|
let sshConfig = `\nHost key-${keyNumber}\n`
|
||||||
|
+ ` HostName github.com\n`
|
||||||
|
+ ` User git\n`
|
||||||
|
+ ` IdentitiesOnly yes\n`
|
||||||
|
+ ` AddKeysToAgent yes\n`
|
||||||
|
+ ` IdentityFile ${keyFile}\n`;
|
||||||
|
|
||||||
|
fs.appendFileSync(`${homeSsh}/config`, sshConfig);
|
||||||
|
|
||||||
|
console.log(`Added deploy-key mapping: Use key #${keyNumber} for GitHub repository ${ownerAndRepo}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("Keys added:");
|
||||||
|
child_process.execSync('ssh-add -l', { stdio: 'inherit' });
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -564,31 +601,6 @@ module.exports = require("path");
|
|||||||
|
|
||||||
module.exports = require("fs");
|
module.exports = require("fs");
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 972:
|
|
||||||
/***/ (function(module, __unusedexports, __webpack_require__) {
|
|
||||||
|
|
||||||
const os = __webpack_require__(87);
|
|
||||||
|
|
||||||
module.exports = (process.env['OS'] != 'Windows_NT') ? {
|
|
||||||
|
|
||||||
// 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
|
|
||||||
home: os.userInfo().homedir,
|
|
||||||
sshAgent: 'ssh-agent',
|
|
||||||
sshAdd: 'ssh-add'
|
|
||||||
|
|
||||||
} : {
|
|
||||||
|
|
||||||
home: os.homedir(),
|
|
||||||
sshAgent: 'c://progra~1//git//usr//bin//ssh-agent.exe',
|
|
||||||
sshAdd: 'c://progra~1//git//usr//bin//ssh-add.exe'
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***/ })
|
/***/ })
|
||||||
|
|
||||||
/******/ });
|
/******/ });
|
||||||
161
index.js
161
index.js
@@ -1,8 +1,9 @@
|
|||||||
const core = require('@actions/core');
|
const core = require('@actions/core');
|
||||||
const child_process = require('child_process');
|
const child_process = require('child_process');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const crypto = require('crypto');
|
const os = require('os');
|
||||||
const { home, sshAgent, sshAdd } = require('./paths.js');
|
const token = require('crypto').randomBytes(64).toString('hex');
|
||||||
|
const isWindows = (process.env['OS'] == 'Windows_NT');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const privateKey = core.getInput('ssh-private-key');
|
const privateKey = core.getInput('ssh-private-key');
|
||||||
@@ -13,76 +14,112 @@ try {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var home;
|
||||||
|
|
||||||
|
if (isWindows) {
|
||||||
|
console.log('Preparing ssh-agent service on Windows');
|
||||||
|
child_process.execSync('sc config ssh-agent start=demand', { stdio: 'inherit' });
|
||||||
|
|
||||||
|
// Work around https://github.com/PowerShell/openssh-portable/pull/447 by creating a \dev\tty file
|
||||||
|
/*fs.mkdirSync('c:\\dev');
|
||||||
|
fs.closeSync(fs.openSync('c:\\dev\\tty', 'a'));
|
||||||
|
fs.mkdirSync('d:\\dev');
|
||||||
|
fs.closeSync(fs.openSync('d:\\dev\\tty', 'a'));*/
|
||||||
|
|
||||||
|
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';
|
const homeSsh = home + '/.ssh';
|
||||||
|
|
||||||
console.log(`Adding GitHub.com keys to ${homeSsh}/known_hosts`);
|
console.log(`Adding GitHub.com keys to ${homeSsh}/known_hosts`);
|
||||||
|
|
||||||
fs.mkdirSync(homeSsh, { recursive: true });
|
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-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');
|
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");
|
console.log("Starting ssh-agent");
|
||||||
|
|
||||||
const authSock = core.getInput('ssh-auth-sock');
|
const authSock = core.getInput('ssh-auth-sock');
|
||||||
const sshAgentArgs = (authSock && authSock.length > 0) ? ['-a', authSock] : [];
|
let sshAgentOutput = ''
|
||||||
|
if (authSock && authSock.length > 0) {
|
||||||
// Extract auth socket path and agent pid and set them as job variables
|
sshAgentOutput = child_process.execFileSync('ssh-agent', ['-a', authSock]);
|
||||||
child_process.execFileSync(sshAgent, sshAgentArgs).toString().split("\n").forEach(function(line) {
|
} else {
|
||||||
const matches = /^(SSH_AUTH_SOCK|SSH_AGENT_PID)=(.*); export \1/.exec(line);
|
sshAgentOutput = child_process.execFileSync('ssh-agent')
|
||||||
|
|
||||||
if (matches && matches.length > 0) {
|
|
||||||
// This will also set process.env accordingly, so changes take effect for this script
|
|
||||||
core.exportVariable(matches[1], matches[2])
|
|
||||||
console.log(`${matches[1]}=${matches[2]}`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("Adding private key(s) to agent");
|
|
||||||
|
|
||||||
privateKey.split(/(?=-----BEGIN)/).forEach(function(key) {
|
|
||||||
child_process.execFileSync(sshAdd, ['-'], { input: key.trim() + "\n" });
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("Key(s) added:");
|
|
||||||
|
|
||||||
child_process.execFileSync(sshAdd, ['-l'], { stdio: 'inherit' });
|
|
||||||
|
|
||||||
console.log('Configuring deployment key(s)');
|
|
||||||
|
|
||||||
child_process.execFileSync(sshAdd, ['-L']).toString().split(/\r?\n/).forEach(function(key) {
|
|
||||||
const parts = key.match(/\bgithub\.com[:/]([_.a-z0-9-]+\/[_.a-z0-9-]+)/i);
|
|
||||||
|
|
||||||
if (!parts) {
|
|
||||||
console.log(`Comment for key '${key}' does not match GitHub URL pattern. Not treating it as a GitHub deploy key.`);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const sha256 = crypto.createHash('sha256').update(key).digest('hex');
|
|
||||||
const ownerAndRepo = parts[1].replace(/\.git$/, '');
|
|
||||||
|
|
||||||
fs.writeFileSync(`${homeSsh}/key-${sha256}`, key + "\n", { mode: '600' });
|
|
||||||
|
|
||||||
child_process.execSync(`git config --global --replace-all url."git@key-${sha256}.github.com:${ownerAndRepo}".insteadOf "https://github.com/${ownerAndRepo}"`);
|
|
||||||
child_process.execSync(`git config --global --add url."git@key-${sha256}.github.com:${ownerAndRepo}".insteadOf "git@github.com:${ownerAndRepo}"`);
|
|
||||||
child_process.execSync(`git config --global --add url."git@key-${sha256}.github.com:${ownerAndRepo}".insteadOf "ssh://git@github.com/${ownerAndRepo}"`);
|
|
||||||
|
|
||||||
const sshConfig = `\nHost key-${sha256}.github.com\n`
|
|
||||||
+ ` HostName github.com\n`
|
|
||||||
+ ` IdentityFile ${homeSsh}/key-${sha256}\n`
|
|
||||||
+ ` IdentitiesOnly yes\n`;
|
|
||||||
|
|
||||||
fs.appendFileSync(`${homeSsh}/config`, sshConfig);
|
|
||||||
|
|
||||||
console.log(`Added deploy-key mapping: Use identity '${homeSsh}/key-${sha256}' for GitHub repository ${ownerAndRepo}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
|
|
||||||
if (error.code == 'ENOENT') {
|
|
||||||
console.log(`The '${error.path}' executable could not be found. Please make sure it is on your PATH and/or the necessary packages are installed.`);
|
|
||||||
console.log(`PATH is set to: ${process.env.PATH}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 keys to agent");
|
||||||
|
var keyNumber = 0;
|
||||||
|
|
||||||
|
privateKey.split(/(?=-----BEGIN)/).forEach(function(key) {
|
||||||
|
++keyNumber;
|
||||||
|
let keyFile = `${homeSsh}/key_${keyNumber}`;
|
||||||
|
|
||||||
|
// Write private key (unencrypted!) to file
|
||||||
|
console.log(`Write file ${keyFile}`);
|
||||||
|
fs.writeFileSync(keyFile, key.replace("\r\n", "\n").trim() + "\n", { mode: '600' });
|
||||||
|
|
||||||
|
// Set private key passphrase
|
||||||
|
let output = '';
|
||||||
|
try {
|
||||||
|
console.log(`Set passphrase on ${keyFile}`);
|
||||||
|
output = child_process.execFileSync('ssh-keygen', ['-p', '-f', keyFile, '-N', token]);
|
||||||
|
} catch (exception) {
|
||||||
|
fs.unlinkSync(keyFile);
|
||||||
|
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load key into agent
|
||||||
|
if (isWindows) {
|
||||||
|
child_process.execFileSync('ssh-add', [keyFile], { env: { ...process.env, ...{ 'DISPLAY': 'fake', 'SSH_PASS': token, 'SSH_ASKPASS': 'D:\\a\\ssh-agent\\ssh-agent\\askpass.exe' } } });
|
||||||
|
} else {
|
||||||
|
child_process.execFileSync('ssh-add', [keyFile], { env: process.env, input: token });
|
||||||
|
}
|
||||||
|
|
||||||
|
output.toString().split(/\r?\n/).forEach(function(key) {
|
||||||
|
let parts = key.match(/^Key has comment '.*\bgithub\.com[:/]([_.a-z0-9-]+\/[_.a-z0-9-]+?)(?=\.git|\s|\')/);
|
||||||
|
|
||||||
|
if (parts == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let ownerAndRepo = parts[1];
|
||||||
|
|
||||||
|
child_process.execSync(`git config --global --replace-all url."git@key-${keyNumber}:${ownerAndRepo}".insteadOf "https://github.com/${ownerAndRepo}"`);
|
||||||
|
child_process.execSync(`git config --global --add url."git@key-${keyNumber}:${ownerAndRepo}".insteadOf "git@github.com:${ownerAndRepo}"`);
|
||||||
|
child_process.execSync(`git config --global --add url."git@key-${keyNumber}:${ownerAndRepo}".insteadOf "ssh://git@github.com/${ownerAndRepo}"`);
|
||||||
|
|
||||||
|
// On Linux and OS X, IdentitiesOnly=no will send all keys from agent before the explicit key, so use "yes".
|
||||||
|
// On Windows, IdentitiesOnly=yes will ignore keys from the agent, but send explicit keys first; so use "no" (https://github.com/PowerShell/Win32-OpenSSH/issues/1550)
|
||||||
|
//let identitiesOnly = isWindows ? 'no' : 'yes';
|
||||||
|
|
||||||
|
let sshConfig = `\nHost key-${keyNumber}\n`
|
||||||
|
+ ` HostName github.com\n`
|
||||||
|
+ ` User git\n`
|
||||||
|
+ ` IdentitiesOnly yes\n`
|
||||||
|
+ ` AddKeysToAgent yes\n`
|
||||||
|
+ ` IdentityFile ${keyFile}\n`;
|
||||||
|
|
||||||
|
fs.appendFileSync(`${homeSsh}/config`, sshConfig);
|
||||||
|
|
||||||
|
console.log(`Added deploy-key mapping: Use key #${keyNumber} for GitHub repository ${ownerAndRepo}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("Keys added:");
|
||||||
|
child_process.execSync('ssh-add -l', { stdio: 'inherit' });
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
}
|
}
|
||||||
|
|||||||
18
paths.js
18
paths.js
@@ -1,18 +0,0 @@
|
|||||||
const os = require('os');
|
|
||||||
|
|
||||||
module.exports = (process.env['OS'] != 'Windows_NT') ? {
|
|
||||||
|
|
||||||
// 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
|
|
||||||
home: os.userInfo().homedir,
|
|
||||||
sshAgent: 'ssh-agent',
|
|
||||||
sshAdd: 'ssh-add'
|
|
||||||
|
|
||||||
} : {
|
|
||||||
|
|
||||||
home: os.homedir(),
|
|
||||||
sshAgent: 'c://progra~1//git//usr//bin//ssh-agent.exe',
|
|
||||||
sshAdd: 'c://progra~1//git//usr//bin//ssh-add.exe'
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user