mirror of
https://github.com/webfactory/ssh-agent.git
synced 2026-03-15 15:59:06 +08:00
Compare commits
27 Commits
debug-wind
...
v0.6.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28cb4d8505 | ||
|
|
ea4c593dc9 | ||
|
|
26e485b72d | ||
|
|
5a6c248f3f | ||
|
|
53715f806b | ||
|
|
19a5c6646f | ||
|
|
fc49353b67 | ||
|
|
bc6614de94 | ||
|
|
dc622c59e4 | ||
|
|
97348a2ec6 | ||
|
|
bbd5513ed5 | ||
|
|
a652a400f2 | ||
|
|
1711bb1971 | ||
|
|
5f066a372e | ||
|
|
a45226bfaf | ||
|
|
81d965f2bd | ||
|
|
515d164e78 | ||
|
|
8569bedfe0 | ||
|
|
98f76b1158 | ||
|
|
cb8b21017a | ||
|
|
aed5400f20 | ||
|
|
4681241867 | ||
|
|
4b6f4eb000 | ||
|
|
795485730f | ||
|
|
598c7ea894 | ||
|
|
65d1ea3d90 | ||
|
|
5f95203cea |
82
.github/workflows/demo.yml
vendored
82
.github/workflows/demo.yml
vendored
@@ -1,60 +1,46 @@
|
||||
on: [push, pull_request]
|
||||
on: [ push, pull_request ]
|
||||
|
||||
jobs:
|
||||
single_key_demo:
|
||||
deployment_keys_demo:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macOS-latest, windows-latest]
|
||||
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 }}
|
||||
- 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
|
||||
|
||||
docker_demo:
|
||||
runs-on: ubuntu-latest
|
||||
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 }}
|
||||
- uses: actions/checkout@v2
|
||||
- run: apt update && apt install -y openssh-client git
|
||||
- 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
|
||||
|
||||
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
|
||||
|
||||
65
CHANGELOG.md
65
CHANGELOG.md
@@ -7,6 +7,71 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## v0.6.0 [2022-10-19]
|
||||
|
||||
### Changed
|
||||
|
||||
* Update the version of Node used by the action from 12 to 16 (https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/).
|
||||
|
||||
## v0.5.4 [2021-11-21]
|
||||
|
||||
### Fixed
|
||||
|
||||
* Update changed GitHub Host Keys (#102, #101)
|
||||
|
||||
### Changed
|
||||
|
||||
* Various documentation (README) improvements and additions
|
||||
* Change logging to more precisely state that _public_ keys are being printed
|
||||
|
||||
## v0.5.3 [2021-06-11]
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed cleanup phase to really terminate the ssh-agent (#80)
|
||||
* Fix termination of ssh-agent also on workflow faiulre (#79)
|
||||
|
||||
### Changed
|
||||
|
||||
* Various documentation (README) improvements and additions
|
||||
|
||||
## v0.5.2 [2021-04-07]
|
||||
|
||||
### Fixed
|
||||
|
||||
* Use case-insensitive regex matching when scanning key comments (#68, #70, #71)
|
||||
|
||||
### Changed
|
||||
|
||||
* Log when a key is _not_ used as a deploy key (#69)
|
||||
|
||||
## v0.5.1 [2021-03-10]
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fix deployment key mapping on Windows virtual environment by using SSH binaries from the Git
|
||||
suite, terminate ssh-agent upon actio termination on Windows as well (#63)
|
||||
* Handle ENOENT exceptions with a graceful message
|
||||
|
||||
### Changed
|
||||
|
||||
* Various documentation (README) improvements and additions
|
||||
|
||||
## v0.5.0 [2021-02-19]
|
||||
|
||||
### Added
|
||||
|
||||
* Add support for GitHub Deployment Keys through key comments (#59). Fixes #30, closes #38.
|
||||
* Support for container-based workflows and Windows (#17)
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fix scripts/build.js to work on Windows (#38)
|
||||
|
||||
### Changed
|
||||
|
||||
* Various documentation (README) improvements and additions
|
||||
|
||||
## v0.4.1 [2020-10-07]
|
||||
|
||||
### Fixed
|
||||
|
||||
78
README.md
78
README.md
@@ -20,11 +20,14 @@ 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.
|
||||
1. Generate a new 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. 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.
|
||||
3. Add the public SSH key to the private repository you are pulling from during the Github Action as a 'Deploy Key'.
|
||||
4. Add the private SSH key to the repository triggering the Github Action:
|
||||
* 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-----`.
|
||||
5. 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
|
||||
@@ -33,9 +36,9 @@ jobs:
|
||||
...
|
||||
steps:
|
||||
- actions/checkout@v2
|
||||
# Make sure the @v0.5.0 matches the current version of the
|
||||
# Make sure the @v0.6.0 matches the current version of the
|
||||
# action
|
||||
- uses: webfactory/ssh-agent@v0.5.0
|
||||
- uses: webfactory/ssh-agent@v0.6.0
|
||||
with:
|
||||
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||
- ... other steps
|
||||
@@ -50,7 +53,7 @@ You can set up different keys as different secrets and pass them all to the acti
|
||||
|
||||
```yaml
|
||||
# ... contens as before
|
||||
- uses: webfactory/ssh-agent@v0.5.0
|
||||
- uses: webfactory/ssh-agent@v0.6.0
|
||||
with:
|
||||
ssh-private-key: |
|
||||
${{ secrets.FIRST_KEY }}
|
||||
@@ -68,7 +71,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.
|
||||
|
||||
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.
|
||||
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"`.)
|
||||
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.
|
||||
@@ -90,6 +93,59 @@ 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 😉.
|
||||
|
||||
## 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.
|
||||
|
||||
### Using the `docker/build-push-action` Action
|
||||
|
||||
If you are using the `docker/build-push-action`, and would like to pass the SSH key, you can do so by adding the following config to pass the socket file through:
|
||||
|
||||
```
|
||||
- name: Build and push
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
ssh: |
|
||||
default=${{ env.SSH_AUTH_SOCK }}
|
||||
```
|
||||
|
||||
### 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
|
||||
|
||||
The following items are not issues, but beyond what this Action is supposed to do.
|
||||
@@ -100,7 +156,7 @@ When using `ssh` to connect from the GitHub Action worker node to another machin
|
||||
|
||||
### 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).
|
||||
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 https://github.com/webfactory/ssh-agent/issues/11).
|
||||
|
||||
### Run `ssh-keyscan` to Add Host Keys for Additional Hosts
|
||||
|
||||
@@ -111,7 +167,7 @@ As a side note, using `ssh-keyscan` without proper key verification is susceptib
|
||||
## 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.
|
||||
If you need to work with some older server software and need RSA keys, try `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
|
||||
@@ -163,4 +219,4 @@ developer looking for new challenges, we'd like to hear from you!
|
||||
- <https://www.webfactory.de>
|
||||
- <https://twitter.com/webfactory>
|
||||
|
||||
Copyright 2019 – 2021 webfactory GmbH, Bonn. Code released under [the MIT license](LICENSE).
|
||||
Copyright 2019 – 2022 webfactory GmbH, Bonn. Code released under [the MIT license](LICENSE).
|
||||
|
||||
@@ -7,9 +7,10 @@ inputs:
|
||||
ssh-auth-sock:
|
||||
description: 'Where to place the SSH Agent auth socket'
|
||||
runs:
|
||||
using: 'node12'
|
||||
using: 'node16'
|
||||
main: 'dist/index.js'
|
||||
post: 'dist/cleanup.js'
|
||||
post-if: 'always()'
|
||||
branding:
|
||||
icon: loader
|
||||
color: 'yellow'
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
const core = require('@actions/core')
|
||||
const { execSync } = require('child_process')
|
||||
const core = require('@actions/core');
|
||||
const { execFileSync } = require('child_process');
|
||||
const { sshAgent } = require('./paths.js');
|
||||
|
||||
try {
|
||||
// Kill the started SSH agent
|
||||
console.log('Stopping SSH agent')
|
||||
execSync('kill ${SSH_AGENT_PID}', { stdio: 'inherit' })
|
||||
console.log('Stopping SSH agent');
|
||||
execFileSync(sshAgent, ['-k'], { stdio: 'inherit' });
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
console.log('Error stopping the SSH agent, proceeding anyway');
|
||||
|
||||
2405
dist/cleanup.js
vendored
2405
dist/cleanup.js
vendored
File diff suppressed because it is too large
Load Diff
2479
dist/index.js
vendored
2479
dist/index.js
vendored
File diff suppressed because it is too large
Load Diff
90
index.js
90
index.js
@@ -1,8 +1,8 @@
|
||||
const core = require('@actions/core');
|
||||
const child_process = require('child_process');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const crypto = require('crypto');
|
||||
const { home, sshAgent, sshAdd } = require('./paths.js');
|
||||
|
||||
try {
|
||||
const privateKey = core.getInput('ssh-private-key');
|
||||
@@ -13,79 +13,77 @@ try {
|
||||
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 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=\n');
|
||||
fs.appendFileSync(`${homeSsh}/known_hosts`, '\ngithub.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl\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');
|
||||
|
||||
console.log("Starting ssh-agent");
|
||||
|
||||
const authSock = core.getInput('ssh-auth-sock');
|
||||
let sshAgentOutput = ''
|
||||
if (authSock && authSock.length > 0) {
|
||||
sshAgentOutput = child_process.execFileSync('ssh-agent', ['-a', authSock]);
|
||||
} else {
|
||||
sshAgentOutput = child_process.execFileSync('ssh-agent')
|
||||
}
|
||||
const sshAgentArgs = (authSock && authSock.length > 0) ? ['-a', authSock] : [];
|
||||
|
||||
// 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])
|
||||
}
|
||||
}
|
||||
child_process.execFileSync(sshAgent, sshAgentArgs).toString().split("\n").forEach(function(line) {
|
||||
const matches = /^(SSH_AUTH_SOCK|SSH_AGENT_PID)=(.*); export \1/.exec(line);
|
||||
|
||||
console.log("Adding private key to agent");
|
||||
privateKey.split(/(?=-----BEGIN)/).forEach(function(key) {
|
||||
child_process.execSync('ssh-add -', { input: key.trim() + "\n" });
|
||||
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("Keys added:");
|
||||
child_process.execSync('ssh-add -l', { stdio: 'inherit' });
|
||||
console.log("Adding private key(s) to agent");
|
||||
|
||||
child_process.execFileSync('ssh-add', ['-L']).toString().split(/\r?\n/).forEach(function(key) {
|
||||
let parts = key.match(/\bgithub.com[:/](.*)(?:\.git)?\b/);
|
||||
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 (public) key '${key}' does not match GitHub URL pattern. Not treating it as a GitHub deploy key.`);
|
||||
|
||||
if (parts == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
let ownerAndRepo = parts[1];
|
||||
let sha256 = crypto.createHash('sha256').update(key).digest('hex');
|
||||
const sha256 = crypto.createHash('sha256').update(key).digest('hex');
|
||||
const ownerAndRepo = parts[1].replace(/\.git$/, '');
|
||||
|
||||
fs.writeFileSync(`${homeSsh}/${sha256}`, key + "\n", { mode: '600' });
|
||||
fs.writeFileSync(`${homeSsh}/key-${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}"`);
|
||||
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}"`);
|
||||
|
||||
let sshConfig = `\nHost ${sha256}\n`
|
||||
const sshConfig = `\nHost key-${sha256}.github.com\n`
|
||||
+ ` HostName github.com\n`
|
||||
+ ` User git\n`
|
||||
+ ` IdentityFile ${homeSsh}/${sha256}\n`
|
||||
+ ` IdentityFile ${homeSsh}/key-${sha256}\n`
|
||||
+ ` IdentitiesOnly yes\n`;
|
||||
|
||||
fs.appendFileSync(`${homeSsh}/config`, sshConfig);
|
||||
|
||||
console.log(`Added deploy-key mapping: Use key "${key}" for GitHub repository ${ownerAndRepo}`);
|
||||
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}`);
|
||||
}
|
||||
|
||||
core.setFailed(error.message);
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
"name": "webfactory-action-ssh-agent",
|
||||
"repository": "git@github.com:webfactory/ssh-agent.git",
|
||||
"description": "GitHub Action to set up ssh-agent with a private SSH key",
|
||||
"version": "0.1.0",
|
||||
"version": "0.6.0",
|
||||
"main": "index.js",
|
||||
"author": "webfactory GmbH <info@webfactory.de>",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@actions/core": "^1.2.4",
|
||||
"@actions/core": "^1.9.1",
|
||||
"@zeit/ncc": "^0.20.5"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
18
paths.js
Normal file
18
paths.js
Normal file
@@ -0,0 +1,18 @@
|
||||
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'
|
||||
|
||||
};
|
||||
|
||||
34
yarn.lock
34
yarn.lock
@@ -2,12 +2,32 @@
|
||||
# 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==
|
||||
"@actions/core@^1.9.1":
|
||||
"integrity" "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA=="
|
||||
"resolved" "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz"
|
||||
"version" "1.9.1"
|
||||
dependencies:
|
||||
"@actions/http-client" "^2.0.1"
|
||||
"uuid" "^8.3.2"
|
||||
|
||||
"@actions/http-client@^2.0.1":
|
||||
"integrity" "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw=="
|
||||
"resolved" "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz"
|
||||
"version" "2.0.1"
|
||||
dependencies:
|
||||
"tunnel" "^0.0.6"
|
||||
|
||||
"@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==
|
||||
"integrity" "sha512-XU6uzwvv95DqxciQx+aOLhbyBx/13ky+RK1y88Age9Du3BlA4mMPCy13BGjayOrrumOzlq1XV3SD/BWiZENXlw=="
|
||||
"resolved" "https://registry.npmjs.org/@zeit/ncc/-/ncc-0.20.5.tgz"
|
||||
"version" "0.20.5"
|
||||
|
||||
"tunnel@^0.0.6":
|
||||
"integrity" "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
|
||||
"resolved" "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz"
|
||||
"version" "0.0.6"
|
||||
|
||||
"uuid@^8.3.2":
|
||||
"integrity" "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
|
||||
"resolved" "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz"
|
||||
"version" "8.3.2"
|
||||
|
||||
Reference in New Issue
Block a user