From 4512be8010f262a32b74d4b4a59300d76bdd43c6 Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Tue, 25 Oct 2022 17:23:31 +0200 Subject: [PATCH 1/8] Update to `actions/checkout@v3` (#143) --- .github/workflows/demo.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/demo.yml b/.github/workflows/demo.yml index 9d8fad0..1cfd2a1 100644 --- a/.github/workflows/demo.yml +++ b/.github/workflows/demo.yml @@ -8,7 +8,7 @@ jobs: os: [ ubuntu-latest, macOS-latest, windows-latest ] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup key uses: ./ with: @@ -28,7 +28,7 @@ jobs: container: image: ubuntu:latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - run: apt update && apt install -y openssh-client git - name: Setup key uses: ./ From 2996779c087b05cb911c8fefc8403a8af8d8f2d4 Mon Sep 17 00:00:00 2001 From: Patrick Higgins Date: Fri, 25 Nov 2022 10:40:39 -0800 Subject: [PATCH 2/8] Replace 0.6.0 references with 0.7.0 in README.md (#153) --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 63d86fd..22c6a25 100644 --- a/README.md +++ b/README.md @@ -36,9 +36,9 @@ jobs: ... steps: - actions/checkout@v2 - # Make sure the @v0.6.0 matches the current version of the + # Make sure the @v0.7.0 matches the current version of the # action - - uses: webfactory/ssh-agent@v0.6.0 + - uses: webfactory/ssh-agent@v0.7.0 with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} - ... other steps @@ -53,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.6.0 + - uses: webfactory/ssh-agent@v0.7.0 with: ssh-private-key: | ${{ secrets.FIRST_KEY }} From 18ff7066d37af765c4268af534ab1500bc3ea7f9 Mon Sep 17 00:00:00 2001 From: kjarkur <108679036+kjarkur@users.noreply.github.com> Date: Fri, 25 Nov 2022 10:44:41 -0800 Subject: [PATCH 3/8] Update README.md (#147) Update `actions/checkout` to `@v3` and make it syntactically correct in order to allow copy and paste. Co-authored-by: Matthias Pigulla --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 22c6a25..c2bdecb 100644 --- a/README.md +++ b/README.md @@ -35,13 +35,12 @@ jobs: my_job: ... steps: - - actions/checkout@v2 - # Make sure the @v0.7.0 matches the current version of the - # action + - uses: actions/checkout@v3 + # Make sure the @v0.7.0 matches the current version of the action - uses: webfactory/ssh-agent@v0.7.0 with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} - - ... other steps + # ... other steps ``` 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. From 209e2d72ff4a448964d26610aceaaf1b3f8764c6 Mon Sep 17 00:00:00 2001 From: kjarkur <108679036+kjarkur@users.noreply.github.com> Date: Fri, 25 Nov 2022 10:45:57 -0800 Subject: [PATCH 4/8] Fix a typo in the README.md (#146) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c2bdecb..c7f826a 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ There are cases where you might need to use multiple keys. For example, "[deploy You can set up different keys as different secrets and pass them all to the action like so: ```yaml -# ... contens as before +# ... contents as before - uses: webfactory/ssh-agent@v0.7.0 with: ssh-private-key: | From 6f828ccb51b0d042f4783ff45710decae9836d37 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Fri, 27 Jan 2023 12:09:18 -0500 Subject: [PATCH 5/8] Allow the user to override the commands for `git`, `ssh-agent`, and `ssh-add` (#154) On my self-hosted Windows runners, the `git`, `ssh-agent`, and `ssh-add` commands are not located in the locations that are currently hard-coded in `paths.js`. With this PR, I am able to get this action to work on my runners as follows: ```yaml - uses: webfactory/ssh-agent@... with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} git-cmd: git ssh-agent-cmd: ssh-agent ssh-add-cmd: ssh-add ``` --- README.md | 3 +++ action.yml | 9 +++++++++ dist/cleanup.js | 12 ++++++------ dist/index.js | 22 +++++++++++++++------- index.js | 10 +++++++++- paths.js | 12 ++++++------ 6 files changed, 48 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index c7f826a..8e2416b 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,9 @@ The following inputs can be used to control the action's behavior: * `ssh-private-key`: Required. Use this to provide the key(s) to load as GitHub Actions secrets. * `ssh-auth-sock`: Can be used to control where the SSH agent socket will be placed. Ultimately affects the `$SSH_AUTH_SOCK` environment variable. * `log-public-key`: Set this to `false` if you want to suppress logging of _public_ key information. To simplify debugging and since it contains public key information only, this is turned on by default. +* `ssh-agent-cmd`: Optional. Use this to specify a custom location for the `ssh-agent` binary. +* `ssh-add-cmd`: Optional. Use this to specify a custom location for the `ssh-add` binary. +* `git-cmd`: Optional. Use this to specify a custom location for the `git` binary. ## Exported variables diff --git a/action.yml b/action.yml index ec3dfd9..4c54ef5 100644 --- a/action.yml +++ b/action.yml @@ -10,6 +10,15 @@ inputs: description: 'Whether or not to log public key fingerprints' required: false default: true + ssh-agent-cmd: + description: 'ssh-agent command' + required: false + ssh-add-cmd: + description: 'ssh-add command' + required: false + git-cmd: + description: 'git command' + required: false runs: using: 'node16' main: 'dist/index.js' diff --git a/dist/cleanup.js b/dist/cleanup.js index 8af40c8..bc904c0 100644 --- a/dist/cleanup.js +++ b/dist/cleanup.js @@ -2827,15 +2827,15 @@ 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 homePath: os.userInfo().homedir, - sshAgentCmd: 'ssh-agent', - sshAddCmd: 'ssh-add', - gitCmd: 'git' + sshAgentCmdDefault: 'ssh-agent', + sshAddCmdDefault: 'ssh-add', + gitCmdDefault: 'git' } : { // Assuming GitHub hosted `windows-*` runners for now homePath: os.homedir(), - sshAgentCmd: 'c://progra~1//git//usr//bin//ssh-agent.exe', - sshAddCmd: 'c://progra~1//git//usr//bin//ssh-add.exe', - gitCmd: 'c://progra~1//git//bin//git.exe' + sshAgentCmdDefault: 'c://progra~1//git//usr//bin//ssh-agent.exe', + sshAddCmdDefault: 'c://progra~1//git//usr//bin//ssh-add.exe', + gitCmdDefault: 'c://progra~1//git//bin//git.exe' }; diff --git a/dist/index.js b/dist/index.js index 3039a0b..ce61449 100644 --- a/dist/index.js +++ b/dist/index.js @@ -322,12 +322,20 @@ const core = __webpack_require__(470); const child_process = __webpack_require__(129); const fs = __webpack_require__(747); const crypto = __webpack_require__(417); -const { homePath, sshAgentCmd, sshAddCmd, gitCmd } = __webpack_require__(972); +const { homePath, sshAgentCmdDefault, sshAddCmdDefault, gitCmdDefault } = __webpack_require__(972); try { const privateKey = core.getInput('ssh-private-key'); const logPublicKey = core.getBooleanInput('log-public-key', {default: true}); + const sshAgentCmdInput = core.getInput('ssh-agent-cmd'); + const sshAddCmdInput = core.getInput('ssh-add-cmd'); + const gitCmdInput = core.getInput('git-cmd'); + + const sshAgentCmd = sshAgentCmdInput ? sshAgentCmdInput : sshAgentCmdDefault + const sshAddCmd = sshAddCmdInput ? sshAddCmdInput : sshAddCmdDefault + const gitCmd = gitCmdInput ? gitCmdInput : gitCmdDefault + 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."); @@ -2906,15 +2914,15 @@ 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 homePath: os.userInfo().homedir, - sshAgentCmd: 'ssh-agent', - sshAddCmd: 'ssh-add', - gitCmd: 'git' + sshAgentCmdDefault: 'ssh-agent', + sshAddCmdDefault: 'ssh-add', + gitCmdDefault: 'git' } : { // Assuming GitHub hosted `windows-*` runners for now homePath: os.homedir(), - sshAgentCmd: 'c://progra~1//git//usr//bin//ssh-agent.exe', - sshAddCmd: 'c://progra~1//git//usr//bin//ssh-add.exe', - gitCmd: 'c://progra~1//git//bin//git.exe' + sshAgentCmdDefault: 'c://progra~1//git//usr//bin//ssh-agent.exe', + sshAddCmdDefault: 'c://progra~1//git//usr//bin//ssh-add.exe', + gitCmdDefault: 'c://progra~1//git//bin//git.exe' }; diff --git a/index.js b/index.js index add5f7c..549bc00 100644 --- a/index.js +++ b/index.js @@ -2,12 +2,20 @@ const core = require('@actions/core'); const child_process = require('child_process'); const fs = require('fs'); const crypto = require('crypto'); -const { homePath, sshAgentCmd, sshAddCmd, gitCmd } = require('./paths.js'); +const { homePath, sshAgentCmdDefault, sshAddCmdDefault, gitCmdDefault } = require('./paths.js'); try { const privateKey = core.getInput('ssh-private-key'); const logPublicKey = core.getBooleanInput('log-public-key', {default: true}); + const sshAgentCmdInput = core.getInput('ssh-agent-cmd'); + const sshAddCmdInput = core.getInput('ssh-add-cmd'); + const gitCmdInput = core.getInput('git-cmd'); + + const sshAgentCmd = sshAgentCmdInput ? sshAgentCmdInput : sshAgentCmdDefault; + const sshAddCmd = sshAddCmdInput ? sshAddCmdInput : sshAddCmdDefault; + const gitCmd = gitCmdInput ? gitCmdInput : gitCmdDefault; + 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."); diff --git a/paths.js b/paths.js index fa2c366..1c6fbf0 100644 --- a/paths.js +++ b/paths.js @@ -4,13 +4,13 @@ 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 homePath: os.userInfo().homedir, - sshAgentCmd: 'ssh-agent', - sshAddCmd: 'ssh-add', - gitCmd: 'git' + sshAgentCmdDefault: 'ssh-agent', + sshAddCmdDefault: 'ssh-add', + gitCmdDefault: 'git' } : { // Assuming GitHub hosted `windows-*` runners for now homePath: os.homedir(), - sshAgentCmd: 'c://progra~1//git//usr//bin//ssh-agent.exe', - sshAddCmd: 'c://progra~1//git//usr//bin//ssh-add.exe', - gitCmd: 'c://progra~1//git//bin//git.exe' + sshAgentCmdDefault: 'c://progra~1//git//usr//bin//ssh-agent.exe', + sshAddCmdDefault: 'c://progra~1//git//usr//bin//ssh-add.exe', + gitCmdDefault: 'c://progra~1//git//bin//git.exe' }; From 9fbc246995ce195568ea31d1110c161283c89684 Mon Sep 17 00:00:00 2001 From: j-riebe <52535122+j-riebe@users.noreply.github.com> Date: Fri, 27 Jan 2023 18:32:35 +0100 Subject: [PATCH 6/8] Clarify usage for Docker build processes, especially with deployment keys (#145) The current docs mention only `docker/build-push-action` in conjunction with deploy keys. This might mislead users to believe, that this only applies to said Action. But the concept applies to all workflows that somehow use `docker build` with deploy keys. This PR clarifies the relevant section. Co-authored-by: Matthias Pigulla --- README.md | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 8e2416b..fdf936f 100644 --- a/README.md +++ b/README.md @@ -112,9 +112,11 @@ If you know that your favorite tool or platform of choice requires extra tweaks 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 +### Building Docker Images and/or 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: +When you are building Docker images with `docker build` or `docker compose build` and need to provide the SSH keys to the build, don't forget to pass `--ssh default=${{ env.SSH_AUTH_SOCK }}` on the command line to pass the SSH agent socket through. See the [Docker documentation](https://docs.docker.com/engine/reference/commandline/buildx_build/#ssh) for more information on this option. + +If you are using the `docker/build-push-action`, you can do so by adding the following config. ```yml - name: Build and push @@ -125,35 +127,45 @@ If you are using the `docker/build-push-action`, and would like to pass the SSH default=${{ env.SSH_AUTH_SOCK }} ``` -### Using the `docker/build-push-action` Action together with multiple Deploy Keys +Make sure not to miss the next section, though. + +### Using Multiple Deploy Keys Inside Docker Builds -If you use the `docker/build-push-action` and want to use multiple GitHub deploy keys, you need to copy the git and ssh configuration to the container during the build. Otherwise, the Docker build process would still not know how to handle multiple deploy keys. Even if the ssh agent was set up correctly on the runner. +When you pass the SSH agent socket to the Docker build environment _and_ want to use multiple GitHub deploy keys, you need to copy the Git and SSH configuration files to the build environment as well. This is necessary _in addition to_ forwarding the SSH agent socket into the build process. The config files are required so that Git can pick the right one from your deployment keys. -This requires an additional step in the actions workflow and two additional lines in the Dockerfile. +This requires an additional step in the workflow file **after** the `ssh-agent` step and **before** the Docker build step. You also need two additional lines in the `Dockerfile` to actually copy the configs. + +The following example will: +* collect the necessary Git and SSH configuration files in a directory that must be part of the Docker build context so that... +* ... the files can be copied into the Docker image (or an intermediate build stage). Workflow: + ```yml - - name: Prepare git and ssh config for build context + - name: ssh-agent setup + ... + + - name: Collect Git and SSH config files in a directory that is part of the Docker build context run: | mkdir root-config cp -r ~/.gitconfig ~/.ssh root-config/ - - name: Build and push - id: docker_build - uses: docker/build-push-action@v2 - with: - ssh: | - default=${{ env.SSH_AUTH_SOCK }} + - name: Docker build + # build-push-action | docker [compose] build | etc. + ... ``` Dockerfile: + ```Dockerfile +# Copy the two files in place and fix different path/locations inside the Docker image COPY root-config /root/ RUN sed 's|/home/runner|/root|g' -i.bak /root/.ssh/config ``` -Have in mind that the Dockerfile now contains customized git and ssh configurations. If you don't want that in your final image, use multi-stage builds. +Keep in mind that the resulting Docker image now might contain these customized Git and SSH configuration files! Your private SSH keys are never written to files anywhere, just loaded into the SSH agent and forwarded into the container. The config files might, however, give away details about your build or development process and contain the names and URLs of your (private) repositories. You might want to use a multi-staged build to make sure these files do not end up in the final image. +If you still get the error message: `fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.`, you most likely forgot one of the steps above. ### Cargo's (Rust) Private Dependencies on Windows From ea17a056b908d85ca1f46c275ab91389eb65c9fa Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Sat, 28 Jan 2023 02:20:24 -0500 Subject: [PATCH 7/8] Add missing semicolons (#159) Follow-up to #154 --- dist/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/index.js b/dist/index.js index ce61449..bdebdb8 100644 --- a/dist/index.js +++ b/dist/index.js @@ -332,9 +332,9 @@ try { const sshAddCmdInput = core.getInput('ssh-add-cmd'); const gitCmdInput = core.getInput('git-cmd'); - const sshAgentCmd = sshAgentCmdInput ? sshAgentCmdInput : sshAgentCmdDefault - const sshAddCmd = sshAddCmdInput ? sshAddCmdInput : sshAddCmdDefault - const gitCmd = gitCmdInput ? gitCmdInput : gitCmdDefault + const sshAgentCmd = sshAgentCmdInput ? sshAgentCmdInput : sshAgentCmdDefault; + const sshAddCmd = sshAddCmdInput ? sshAddCmdInput : sshAddCmdDefault; + const gitCmd = gitCmdInput ? gitCmdInput : gitCmdDefault; 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."); From d4b9b8ff72958532804b70bbe600ad43b36d5f2e Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Fri, 24 Mar 2023 12:15:25 +0100 Subject: [PATCH 8/8] Stop adding GitHub SSH keys (#171) We need to fix the SSH keys shipped with this action: https://github.blog/2023-03-23-we-updated-our-rsa-ssh-host-key/ But, we have another issue (https://github.com/webfactory/ssh-agent/pull/108) with regards to host keys: On self-hosted runners which are not ephemeral the known_host file fills up with repeated entries, because every action run adds a new line with the same host keys. Also, on those machines, the old key will still be in the `known_hosts` file. IMHO this action should not be repsonsible for shipping SSH host keys, that's too much responsibility. This section in the code is a leftover from early days when GitHub provided runners did not include SSH keys at all. For a long time already, GH takes care of placing their SSH keys in their runner images. For self-hosted runners, those people setting up the runner should fetch and verify SSH keys themselves and put it into the `known_hosts` file. I know this is a breaking change and is going to annoy users. But on the other hand, there is no better opportunity to drop this feature than with an emergency-style key revocation as today. Closes #106, closes #129, closes #169, closes #170, closes #172. --- README.md | 2 +- dist/cleanup.js | 57 +++++++++++++++++++++++++++----------------- dist/index.js | 63 ++++++++++++++++++++++++++++--------------------- index.js | 6 ----- 4 files changed, 73 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index fdf936f..46c74a5 100644 --- a/README.md +++ b/README.md @@ -272,4 +272,4 @@ developer looking for new challenges, we'd like to hear from you! - - -Copyright 2019 – 2022 webfactory GmbH, Bonn. Code released under [the MIT license](LICENSE). +Copyright 2019 – 2023 webfactory GmbH, Bonn. Code released under [the MIT license](LICENSE). diff --git a/dist/cleanup.js b/dist/cleanup.js index bc904c0..61fc276 100644 --- a/dist/cleanup.js +++ b/dist/cleanup.js @@ -292,13 +292,14 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.issueCommand = void 0; +exports.prepareKeyValueMessage = exports.issueFileCommand = void 0; // 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 uuid_1 = __webpack_require__(62); const utils_1 = __webpack_require__(82); -function issueCommand(command, message) { +function issueFileCommand(command, message) { const filePath = process.env[`GITHUB_${command}`]; if (!filePath) { throw new Error(`Unable to find environment variable for file command ${command}`); @@ -310,7 +311,22 @@ function issueCommand(command, message) { encoding: 'utf8' }); } -exports.issueCommand = issueCommand; +exports.issueFileCommand = issueFileCommand; +function prepareKeyValueMessage(key, value) { + const delimiter = `ghadelimiter_${uuid_1.v4()}`; + const convertedValue = utils_1.toCommandValue(value); + // These should realistically never happen, but just in case someone finds a + // way to exploit uuid generation let's not allow keys or values that contain + // the delimiter. + if (key.includes(delimiter)) { + throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); + } + if (convertedValue.includes(delimiter)) { + throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`); + } + return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`; +} +exports.prepareKeyValueMessage = prepareKeyValueMessage; //# sourceMappingURL=file-command.js.map /***/ }), @@ -1668,7 +1684,6 @@ 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)); -const uuid_1 = __webpack_require__(62); const oidc_utils_1 = __webpack_require__(742); /** * The code to exit an action @@ -1698,20 +1713,9 @@ function exportVariable(name, val) { process.env[name] = convertedVal; const filePath = process.env['GITHUB_ENV'] || ''; if (filePath) { - const delimiter = `ghadelimiter_${uuid_1.v4()}`; - // These should realistically never happen, but just in case someone finds a way to exploit uuid generation let's not allow keys or values that contain the delimiter. - if (name.includes(delimiter)) { - throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); - } - if (convertedVal.includes(delimiter)) { - throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`); - } - const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`; - file_command_1.issueCommand('ENV', commandValue); - } - else { - command_1.issueCommand('set-env', { name }, convertedVal); + return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); } + command_1.issueCommand('set-env', { name }, convertedVal); } exports.exportVariable = exportVariable; /** @@ -1729,7 +1733,7 @@ exports.setSecret = setSecret; function addPath(inputPath) { const filePath = process.env['GITHUB_PATH'] || ''; if (filePath) { - file_command_1.issueCommand('PATH', inputPath); + file_command_1.issueFileCommand('PATH', inputPath); } else { command_1.issueCommand('add-path', {}, inputPath); @@ -1769,7 +1773,10 @@ function getMultilineInput(name, options) { const inputs = getInput(name, options) .split('\n') .filter(x => x !== ''); - return inputs; + if (options && options.trimWhitespace === false) { + return inputs; + } + return inputs.map(input => input.trim()); } exports.getMultilineInput = getMultilineInput; /** @@ -1802,8 +1809,12 @@ exports.getBooleanInput = getBooleanInput; */ // eslint-disable-next-line @typescript-eslint/no-explicit-any function setOutput(name, value) { + const filePath = process.env['GITHUB_OUTPUT'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value)); + } process.stdout.write(os.EOL); - command_1.issueCommand('set-output', { name }, value); + command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value)); } exports.setOutput = setOutput; /** @@ -1932,7 +1943,11 @@ exports.group = group; */ // eslint-disable-next-line @typescript-eslint/no-explicit-any function saveState(name, value) { - command_1.issueCommand('save-state', { name }, value); + const filePath = process.env['GITHUB_STATE'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('STATE', file_command_1.prepareKeyValueMessage(name, value)); + } + command_1.issueCommand('save-state', { name }, utils_1.toCommandValue(value)); } exports.saveState = saveState; /** diff --git a/dist/index.js b/dist/index.js index bdebdb8..2c23f23 100644 --- a/dist/index.js +++ b/dist/index.js @@ -292,13 +292,14 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.issueCommand = void 0; +exports.prepareKeyValueMessage = exports.issueFileCommand = void 0; // 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 uuid_1 = __webpack_require__(62); const utils_1 = __webpack_require__(82); -function issueCommand(command, message) { +function issueFileCommand(command, message) { const filePath = process.env[`GITHUB_${command}`]; if (!filePath) { throw new Error(`Unable to find environment variable for file command ${command}`); @@ -310,7 +311,22 @@ function issueCommand(command, message) { encoding: 'utf8' }); } -exports.issueCommand = issueCommand; +exports.issueFileCommand = issueFileCommand; +function prepareKeyValueMessage(key, value) { + const delimiter = `ghadelimiter_${uuid_1.v4()}`; + const convertedValue = utils_1.toCommandValue(value); + // These should realistically never happen, but just in case someone finds a + // way to exploit uuid generation let's not allow keys or values that contain + // the delimiter. + if (key.includes(delimiter)) { + throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); + } + if (convertedValue.includes(delimiter)) { + throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`); + } + return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`; +} +exports.prepareKeyValueMessage = prepareKeyValueMessage; //# sourceMappingURL=file-command.js.map /***/ }), @@ -343,13 +359,7 @@ try { } const homeSsh = homePath + '/.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'); console.log("Starting ssh-agent"); @@ -1755,7 +1765,6 @@ 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)); -const uuid_1 = __webpack_require__(62); const oidc_utils_1 = __webpack_require__(742); /** * The code to exit an action @@ -1785,20 +1794,9 @@ function exportVariable(name, val) { process.env[name] = convertedVal; const filePath = process.env['GITHUB_ENV'] || ''; if (filePath) { - const delimiter = `ghadelimiter_${uuid_1.v4()}`; - // These should realistically never happen, but just in case someone finds a way to exploit uuid generation let's not allow keys or values that contain the delimiter. - if (name.includes(delimiter)) { - throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); - } - if (convertedVal.includes(delimiter)) { - throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`); - } - const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`; - file_command_1.issueCommand('ENV', commandValue); - } - else { - command_1.issueCommand('set-env', { name }, convertedVal); + return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); } + command_1.issueCommand('set-env', { name }, convertedVal); } exports.exportVariable = exportVariable; /** @@ -1816,7 +1814,7 @@ exports.setSecret = setSecret; function addPath(inputPath) { const filePath = process.env['GITHUB_PATH'] || ''; if (filePath) { - file_command_1.issueCommand('PATH', inputPath); + file_command_1.issueFileCommand('PATH', inputPath); } else { command_1.issueCommand('add-path', {}, inputPath); @@ -1856,7 +1854,10 @@ function getMultilineInput(name, options) { const inputs = getInput(name, options) .split('\n') .filter(x => x !== ''); - return inputs; + if (options && options.trimWhitespace === false) { + return inputs; + } + return inputs.map(input => input.trim()); } exports.getMultilineInput = getMultilineInput; /** @@ -1889,8 +1890,12 @@ exports.getBooleanInput = getBooleanInput; */ // eslint-disable-next-line @typescript-eslint/no-explicit-any function setOutput(name, value) { + const filePath = process.env['GITHUB_OUTPUT'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value)); + } process.stdout.write(os.EOL); - command_1.issueCommand('set-output', { name }, value); + command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value)); } exports.setOutput = setOutput; /** @@ -2019,7 +2024,11 @@ exports.group = group; */ // eslint-disable-next-line @typescript-eslint/no-explicit-any function saveState(name, value) { - command_1.issueCommand('save-state', { name }, value); + const filePath = process.env['GITHUB_STATE'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('STATE', file_command_1.prepareKeyValueMessage(name, value)); + } + command_1.issueCommand('save-state', { name }, utils_1.toCommandValue(value)); } exports.saveState = saveState; /** diff --git a/index.js b/index.js index 549bc00..0c2e08b 100644 --- a/index.js +++ b/index.js @@ -23,13 +23,7 @@ try { } const homeSsh = homePath + '/.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'); console.log("Starting ssh-agent");