Compare commits

...

61 Commits
v2.1.0 ... v2

Author SHA1 Message Date
shimataro d4fffb5087
version 2.7.0 (#270) 2024-02-11 11:30:38 +09:00
shimataro 9383557752
update dependencies (#269) 2024-02-11 11:18:12 +09:00
shimataro 8f0e25e199
Feature/node20 (#268)
* Update to Node 20 (#267)

* Update action.yml

* Update build.yml

* update CHANGELOG

* Drop old containers

* update CHANGELOG

---------

Co-authored-by: Po Chen <chenpaul914@gmail.com>
2024-02-11 11:04:28 +09:00
shimataro 38b53cb2f4
version 2.6.1 (#264) 2023-10-13 10:02:31 +09:00
shimataro 9e1a5e7913
use cache for npm (#263) 2023-10-13 09:39:50 +09:00
shimataro c858f8173b
update dependencies (#262) 2023-10-13 09:06:52 +09:00
shimataro f848d33143
fix; release script error (#261) 2023-10-12 10:27:38 +09:00
shimataro b49a036be4
fix; JSON parse error on exit, if `if_key_exists`=`fail` and key exists (#260)
* fix; JSON parse error on exit, if `if_key_exists`=`fail` and key exists

* update CHANGELOG

* fix cleanup error

* add built files

* output only if created/removed/restored file exist.
2023-10-12 09:58:46 +09:00
shimataro 18e8292da0
update release script (#259) 2023-10-12 05:00:12 +09:00
shimataro d05e1bdf7d
Merge pull request #258 from shimataro/develop
version 2.6.0
2023-10-12 04:11:09 +09:00
shimataro a9c5970ee8
version 2.6.0 (#257) 2023-10-11 22:58:33 +09:00
shimataro ccfb951a8e
fix; files that didn't backed up is not removed in "post" phase (#256)
* fix; files that didn't backed up is not removed in "post" phase

* output logs

* output log in main phase

* update log text

* update log text

* create directory only if not exist

* amend step name
2023-10-11 16:20:54 +09:00
shimataro ab731d2fcd
update dependencies (#255) 2023-10-11 07:44:42 +09:00
shimataro 51874aa964
exit if differ (#254) 2023-10-11 05:25:38 +09:00
shimataro 00676f1f60
use `os.homedir()` in order to get home directory (#253) 2023-10-11 05:04:21 +09:00
shimataro 6948892be9
use module files (#252)
* use module

* detect files to be restore automatically

* use esbuild

* drop ncc

* add comments

* refactor
2023-10-11 04:35:20 +09:00
shimataro 31d4b8b483
backup & restore (#251)
* backup & restore

* refactor

* refactor

* back up key file

* fix messages

* update CHANGELOG

* update CHANGELOG
2023-10-10 13:51:45 +09:00
shimataro 2983fc456f
Feature/remove old runner (#249)
* Drop runnner: macOS 10.15, Ubuntu 18.04

* update README

* update CHANGELOG

* update key of bitbucket.com
2023-10-09 18:25:53 +09:00
shimataro f5671c022c
update dependencies (#241) 2023-03-25 05:53:47 +09:00
shimataro 685d0f20da
Merge pull request #240 from shimataro/develop
version 2.5.1
2023-03-25 05:13:30 +09:00
shimataro 699cc3af2a
version 2.5.1 (#239) 2023-03-25 04:53:10 +09:00
shimataro 18601dcd44
Feature/update gh key (#238)
* github: Update SSH key

Signed-off-by: Ryan Northey <ryan@synca.io>

* update GitHub key: https://github.blog/2023-03-23-we-updated-our-rsa-ssh-host-key/

* add name

---------

Signed-off-by: Ryan Northey <ryan@synca.io>
Co-authored-by: Ryan Northey <ryan@synca.io>
2023-03-25 04:27:28 +09:00
shimataro 02d189fc92
Merge pull request #230 from shimataro/develop
version 2.5.0
2022-12-24 21:59:35 +09:00
shimataro 70366947e2
version 2.5.0 (#229) 2022-12-24 21:37:26 +09:00
shimataro 00376433fd
update dependencies (#228) 2022-12-24 20:55:12 +09:00
shimataro d3bad3234b
update dependencies (#227) 2022-12-21 17:36:57 +09:00
shimataro c8a575584e
set workflow name (#226)
* set workflow name

* update actions/checkout version: v2 -> v3

* update actions/setup-node version: v1 -> v3
2022-12-21 11:14:30 +09:00
shimataro da84e6bf98
Feature/ci (#225)
* reuse workflows
https://docs.github.com/en/actions/using-workflows/reusing-workflows

* reuse container workflows

* integrate reusable-verify-container with reusable-verify

* container -> docker_iamge

* update description
2022-12-20 22:11:39 +09:00
shimataro 7cccbd3065
add cleanup process (#224)
* add cleanup process

* save state

* update README/CHANGELOG

* fix message

* `getSshDirectory()` should not be exported
2022-12-20 08:06:55 +09:00
shimataro 86a65fd09b
Merge pull request #222 from shimataro/develop
version 2.4.0
2022-11-03 05:05:47 +09:00
shimataro 193316a178
version 2.4.0 (#221) 2022-11-03 04:41:33 +09:00
shimataro a3a8a38571
update dependencies (#220) 2022-11-03 04:12:51 +09:00
shimataro 1512adeca4
Feature/GitHub key (#122)
* always prepend key of github.com

* update README and CHANGELOG

* update tests

* test to connect bitbucket.org

* update test

* update rest tests
2022-11-03 03:41:25 +09:00
shimataro bcb314ec07
fix usage of rsync (#218) 2022-10-31 00:31:19 +09:00
shimataro 53a7c26e5e
Feature/runners (#217)
* Updated runners list and tar updated to 6.1.11

* Updated runners list

* Added nodejs 16

* Updated .gitignore

* some adjusts

* update CHANGELOG

Co-authored-by: Viacheslav Kudinov <viacheslav.kudinov@gmail.com>
2022-10-30 23:46:03 +09:00
shimataro fc21805258
Update nodejs version to 16 (#208) (#216)
* Update nodejs version to 16 (#208)

* Update nodejs version to 16

* Update runtime used to node16

* update CHANGELOG

Co-authored-by: Davide Doronzo <duddu@users.noreply.github.com>
2022-10-30 22:47:45 +09:00
shimataro 1926ba6435
update dependencies (#211) 2022-10-30 21:57:29 +09:00
shimataro adea214356
Feature/refactor (#209)
* Change code style to 1TBS

* refactor creating ".ssh" directoy

* Add Windows-2022 / macOS-11 / macOS-12 / Ubuntu-22.04
Drop Ubuntu-16.04

* Drop centos:8 (Docker container)

* add CentOS 8 Stream (Docker container)

* use YAML alias

* Revert "use YAML alias"

This reverts commit 1ddbc7fde8.

* update .eslintrc

* move calling main to front
2022-10-30 19:57:06 +09:00
shimataro 3c9b0fc6f2
Merge pull request #190 from shimataro/develop
version 2.3.1
2021-08-01 23:19:32 +09:00
shimataro b38d88da8a
version 2.3.1 (#189) 2021-08-01 23:04:08 +09:00
shimataro 92fef6465a
Feature/virtual environments (#187)
* remove ubuntu-16.04 virtual environment; https://github.blog/changelog/2021-04-29-github-actions-ubuntu-16-04-lts-virtual-environment-will-be-removed-on-september-20-2021/

* add `windows-2016` virtual environment

* update README/CHANGELOG

* remove ubuntu-16.04
fix tests on Windows/macOS
2021-08-01 22:31:32 +09:00
shimataro a46749e290
Feature/update dependencies 20210801 (#186)
* update dependencies

* update CHANGELOG
2021-08-01 21:52:23 +09:00
shimataro ce5317ebbf
Merge pull request #183 from shimataro/develop
version 2.3.0
2021-03-21 16:25:36 +09:00
shimataro 4dfaf8f393
version 2.3.0 (#182) 2021-03-21 16:05:33 +09:00
shimataro 954c620b17
Feature/no known hosts (#181)
* add "if_key_exists"

* add test

* fix flag

* fix SSH connection commands

* add test for if_key_exists=ignore

* add test for if_key_exists=fail

* add tests to Windows / macOS

* update CHANGELOG

* update badges

* update README

* fix README

* update README

* test no_known_hosts parameter

* implement

* ignore known_hosts if no_known_hosts is true

* refactor

* no_known_hosts is false

* Revert "no_known_hosts is false"

This reverts commit 206d310c5c.

* test on Windows / macOS

* test on Docker containers

* add tests for Docker containers

* test no_known_hosts parameter

* implement

* ignore known_hosts if no_known_hosts is true

* refactor

* no_known_hosts is false

* Revert "no_known_hosts is false"

This reverts commit 206d310c5c.

* test on Windows / macOS

* test on Docker containers

* use `known_hosts: no` instead of `no_known_hosts: true`

* update README

* update README

* "known_hosts: no" -> "known_hosts: unnecessary"

* update README

* update README

* update CHANGELOG
2021-03-21 15:43:28 +09:00
shimataro f8aa6610de
Feature/verify on container alpine (#180)
* support Alpine Docker container

* add Git package

* update README

* update README; add install commands

* update CHANGELOG

* fix typo

* fix typo
2021-03-21 14:56:48 +09:00
shimataro 88fb14d113
add "if_key_exists" (#179)
* add "if_key_exists"

* add test

* fix flag

* fix SSH connection commands

* add test for if_key_exists=ignore

* add test for if_key_exists=fail

* add tests to Windows / macOS

* update CHANGELOG

* update badges

* update README

* fix README

* update README

* add tests for Docker containers
2021-03-18 20:57:28 +09:00
shimataro 0bbd533afd
Merge pull request #178 from shimataro/develop
version 2.2.0
2021-02-27 14:16:22 +09:00
shimataro 8053198ce5
version 2.2.0 (#177) 2021-02-27 14:09:25 +09:00
shimataro 68b956be12
Feature/centos (#176)
* check on CentOS container

* update README

* update links

* update CHANGELOG

* refactor insertLf()
2021-02-24 21:24:03 +09:00
shimataro cdcc4725b3
test on Docker for Windows (#175)
* test on Docker for Windows

* Revert "test on Docker for Windows"

This reverts commit 5ad4baf9d8.

* update README
2021-02-23 11:27:02 +09:00
shimataro 80ed341cfe
update dependencies (#174) 2021-02-23 10:42:34 +09:00
shimataro 4b6bc79244
Feature/matrix docker container (#173)
* use matrix for Docker container

* update badge
2021-02-23 10:38:18 +09:00
shimataro 5b144c9cec
remove "pull_request" trigger from CI (#172) 2021-02-23 10:25:44 +09:00
shimataro e83b5ac86d
support OpenSSH key format (#171)
* Make up for LF in last line of SSH key file

* refactor insertLf()

* add test for OpenSSH format

* add PKCS8 format

* apply to other virtual machines

* update README

* update CHANGELOG

Co-authored-by: Tatsunori Uchino <tats.u@live.jp>
2021-02-23 10:22:30 +09:00
shimataro 026e5f82bf
Feature/container (#170)
* support Docker container

* move .ssh to /root

* remove print step

* change home directory for Docker container

* print HOME

* print home

* print home

* update dist file

* update dirname

* update CHANGELOG

* add badge
2021-02-08 23:31:19 +09:00
shimataro 0b924ac88f
update dependencies (#169) 2021-02-08 22:40:11 +09:00
shimataro a988908393
Feature/ignore node modules (#166)
* Ignore Node files that should not be tracked

The list can be fetched by `gibo dump node`.

* Untrack node_modules/@actions

* Cache node_modules

* Don't add node_modules ins Bash scripts

* Use ncc to pack dependencies

* Change final product path

Remove & ignore previous one (lib/main.js{,.map})

* Disable PR check using author's key

Author's key is not passed to PR builds (#164)

* update settings

* update CHANGELOG

* update build.yml

Co-authored-by: Tatsunori Uchino <tats.u@live.jp>
2021-02-08 22:19:05 +09:00
shimataro 47a775a015
Feature/fix readme (#167)
* fix README.md

* update README

Co-authored-by: KimSoungRyoul <KimSoungRyoul@gmail.com>
2021-02-08 21:40:22 +09:00
dependabot[bot] 66374eaff9
Bump @actions/core from 1.2.4 to 1.2.6 (#158)
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.2.4 to 1.2.6.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-10-10 22:53:14 +09:00
shimataro c1b9a14080
Feature/funding (#155)
* Create FUNDING.yml

* add PayPal.ME URL
2020-09-03 00:40:40 +09:00
46 changed files with 11607 additions and 3866 deletions

View File

@ -25,6 +25,13 @@ spaces_around_brackets = none
indent_brace_style = allman
# JavaScript/TypeScript
[*.{js,ts}]
indent_style = space
curly_bracket_next_line = false
indent_brace_style = K&R
# JSON/YAML
[*.{json,babelrc,code-workspace,yml,yaml}]
indent_style = space

View File

@ -14,7 +14,9 @@ parserOptions:
project: ./tsconfig.json
rules: # https://eslint.org/docs/rules/
accessor-pairs: error
array-bracket-newline: error
array-bracket-newline:
- error
- consistent
array-bracket-spacing:
- error
- never
@ -29,9 +31,7 @@ rules: # https://eslint.org/docs/rules/
before: true
block-scoped-var: error
block-spacing: error
brace-style:
- error
- allman
brace-style: 'off' # see "@typescript-eslint/brace-style"
callback-return: error
capitalized-comments: 'off'
class-methods-use-this: error
@ -87,26 +87,14 @@ rules: # https://eslint.org/docs/rules/
- below
indent:
- error
- tab
- 4
- SwitchCase: 1
indent-legacy: 'off'
init-declarations: error
jsx-quotes: error
key-spacing: error
keyword-spacing:
- error
- overrides:
catch:
after: false
for:
after: false
if:
after: false
switch:
after: false
while:
after: false
with:
after: false
line-comment-position: 'off'
linebreak-style:
- error
@ -173,7 +161,7 @@ rules: # https://eslint.org/docs/rules/
- error
- max: 1
no-native-reassign: error
no-negated-condition: error
no-negated-condition: 'off'
no-negated-in-lhs: error
no-nested-ternary: error
no-new: error
@ -256,7 +244,7 @@ rules: # https://eslint.org/docs/rules/
rest-spread-spacing:
- error
- never
semi: error
semi: 'off' # see "@typescript-eslint/semi"
semi-spacing: error
semi-style:
- error
@ -308,8 +296,25 @@ rules: # https://eslint.org/docs/rules/
# @typescript-eslint plugin
"@typescript-eslint/ban-ts-ignore": 'off'
"@typescript-eslint/brace-style":
- error
- 1tbs
"@typescript-eslint/member-delimiter-style":
- error
- multiline:
delimiter: semi
requireLast: true
singleline:
delimiter: semi
requireLast: true
"@typescript-eslint/no-empty-interface": 'off'
"@typescript-eslint/no-floating-promises": error
"@typescript-eslint/no-use-before-define":
- error
- functions: false
"@typescript-eslint/strict-boolean-expressions": error
"@typescript-eslint/semi": error
"@typescript-eslint/strict-boolean-expressions":
- error
- allowString: false
allowNumber: false
allowNullableObject: false

4
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,4 @@
github:
- shimataro
custom:
- "https://www.paypal.me/shimataro"

25
.github/actions/cache-npm/action.yml vendored Normal file
View File

@ -0,0 +1,25 @@
# https://docs.github.com/en/actions/creating-actions/creating-a-composite-action
name: Cache NPM
description: Composite action (cache NPM)
runs:
using: composite
steps:
# https://github.com/actions/cache/blob/master/examples.md#node---npm
# https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter
- name: Get NPM cache directory
run: echo "NPM_CACHE_DIRECTORY=$(npm config get cache)" >> ${{ github.env }} # use "github.env" instead of "github.output"; if use "github.output", "Warning: Input required and not supplied: path" is displayed on post-process
shell: pwsh # use PowerShell; Bash doesn't work on Windows because the value of "github.env" is like "D:\a\_temp\_runner_file_commands\set_env_XXX".
- name: Get Node.js version
run: echo "NODEJS_VERSION=$(node -v)" >> ${{ github.env }}
shell: pwsh
- name: Cache NPM modules
uses: actions/cache@v3
with:
path: ${{ env.NPM_CACHE_DIRECTORY }}
key: npm-${{ runner.os }}-${{ runner.arch }}-${{ env.NODEJS_VERSION }}-${{ hashFiles('package-lock.json') }}
restore-keys: |
npm-${{ runner.os }}-${{ runner.arch }}-${{ env.NODEJS_VERSION }}-
npm-${{ runner.os }}-${{ runner.arch }}

View File

@ -4,7 +4,6 @@ name: Build
on:
- push
- pull_request
jobs:
build:
@ -13,26 +12,31 @@ jobs:
strategy:
matrix:
os:
- Windows-2019
- macOS-10.15
- Ubuntu-16.04
- Ubuntu-18.04
- Ubuntu-20.04
- windows-2019
- windows-2022
- macos-11
- macos-12
- ubuntu-20.04
- ubuntu-22.04
nodejs:
- 12
- 20
fail-fast: false
steps:
- name: Turn off auto-crlf
run: git config --global core.autocrlf false
- name: Checkout source codes
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Install Node.js
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.nodejs }}
- name: Cache NPM
uses: ./.github/actions/cache-npm
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Exit if differ (forgot to commit dist dir?)
run: git diff --exit-code --quiet
- name: Verify
run: npm run verify

278
.github/workflows/reusable-verify.yml vendored Normal file
View File

@ -0,0 +1,278 @@
# https://docs.github.com/en/actions/using-workflows/reusing-workflows
name: Reusable workflow (verify)
on:
workflow_call:
inputs:
os:
required: true
type: string
description: host OS that CI 'runs-on'
docker_image:
required: false
type: string
default: ""
description: Docker image name
package_installation_command:
required: false
type: string
default: ""
description: package installation command
secrets:
SSH_KEY_PEM:
required: true
description: SSH private key (PEM format)
SSH_KEY_PKCS8:
required: true
description: SSH private key (PKCS8 format)
SSH_KEY_RFC4716:
required: true
description: SSH private key (RFC4716 format)
jobs:
ssh-pem:
name: Connect to github.com (PEM format)
runs-on: ${{ inputs.os }}
container: ${{ inputs.docker_image }}
steps:
- name: Install packages
run: ${{ inputs.package_installation_command }}
if: ${{ inputs.package_installation_command != '' }}
- name: Checkout source codes
uses: actions/checkout@v3
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY_PEM }}
known_hosts: unnecessary
- name: git clone through SSH
run: git clone git@github.com:shimataro/ssh-key-action.git tmp
ssh-pem-bitbucket:
name: Connect to bitbucket.org (PEM format)
runs-on: ${{ inputs.os }}
container: ${{ inputs.docker_image }}
steps:
- name: Install packages
run: ${{ inputs.package_installation_command }}
if: ${{ inputs.package_installation_command != '' }}
- name: Checkout source codes
uses: actions/checkout@v3
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY_PEM }}
known_hosts: |
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
bitbucket.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIQmuzMBuKdWeF4+a2sjSSpBK0iqitSQ+5BM9KhpexuGt20JpTVM7u5BDZngncgrqDMbWdxMWWOGtZ9UgbqgZE=
bitbucket.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIazEu89wgQZ4bqs3d63QSMzYVa0MuJ2e2gKTKqu+UUO
- name: git clone through SSH
run: git clone git@bitbucket.org:shimataro999/ssh-test.git tmp
ssh-pkcs8:
name: Connect to github.com (PKCS8 format)
runs-on: ${{ inputs.os }}
container: ${{ inputs.docker_image }}
steps:
- name: Install packages
run: ${{ inputs.package_installation_command }}
if: ${{ inputs.package_installation_command != '' }}
- name: Checkout source codes
uses: actions/checkout@v3
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY_PKCS8 }}
known_hosts: unnecessary
- name: git clone through SSH
run: git clone git@github.com:shimataro/ssh-key-action.git tmp
ssh-pkcs8-bitbucket:
name: Connect to bitbucket.org (PKCS8 format)
runs-on: ${{ inputs.os }}
container: ${{ inputs.docker_image }}
steps:
- name: Install packages
run: ${{ inputs.package_installation_command }}
if: ${{ inputs.package_installation_command != '' }}
- name: Checkout source codes
uses: actions/checkout@v3
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY_PKCS8 }}
known_hosts: |
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
bitbucket.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIQmuzMBuKdWeF4+a2sjSSpBK0iqitSQ+5BM9KhpexuGt20JpTVM7u5BDZngncgrqDMbWdxMWWOGtZ9UgbqgZE=
bitbucket.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIazEu89wgQZ4bqs3d63QSMzYVa0MuJ2e2gKTKqu+UUO
- name: git clone through SSH
run: git clone git@bitbucket.org:shimataro999/ssh-test.git tmp
ssh-rfc4716:
name: Connect to github.com (RFC4716 format)
runs-on: ${{ inputs.os }}
container: ${{ inputs.docker_image }}
steps:
- name: Install packages
run: ${{ inputs.package_installation_command }}
if: ${{ inputs.package_installation_command != '' }}
- name: Checkout source codes
uses: actions/checkout@v3
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY_RFC4716 }}
known_hosts: unnecessary
- name: git clone through SSH
run: git clone git@github.com:shimataro/ssh-key-action.git tmp
ssh-rfc4716-bitbucket:
name: Connect to bitbucket.org (RFC4716 format)
runs-on: ${{ inputs.os }}
container: ${{ inputs.docker_image }}
steps:
- name: Install packages
run: ${{ inputs.package_installation_command }}
if: ${{ inputs.package_installation_command != '' }}
- name: Checkout source codes
uses: actions/checkout@v3
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY_RFC4716 }}
known_hosts: |
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
bitbucket.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIQmuzMBuKdWeF4+a2sjSSpBK0iqitSQ+5BM9KhpexuGt20JpTVM7u5BDZngncgrqDMbWdxMWWOGtZ9UgbqgZE=
bitbucket.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIazEu89wgQZ4bqs3d63QSMzYVa0MuJ2e2gKTKqu+UUO
- name: git clone through SSH
run: git clone git@bitbucket.org:shimataro999/ssh-test.git tmp
key_if_exists_replace-key_exists:
name: if_key_exists=replace / key exists
runs-on: ${{ inputs.os }}
container: ${{ inputs.docker_image }}
steps:
- name: Install packages
run: ${{ inputs.package_installation_command }}
if: ${{ inputs.package_installation_command != '' }}
- name: Checkout source codes
uses: actions/checkout@v3
- name: Install SSH key (dummy)
uses: ./.
with:
key: "dummy" # replaced
known_hosts: unnecessary
- name: Install SSH key (replaces existing key)
uses: ./.
with:
key: ${{ secrets.SSH_KEY_PEM }}
known_hosts: unnecessary
if_key_exists: replace
- name: git clone through SSH
run: git clone git@github.com:shimataro/ssh-key-action.git tmp
key_if_exists_replace-key_doesnt_exist:
name: if_key_exists=replace / key doesn't exist
runs-on: ${{ inputs.os }}
container: ${{ inputs.docker_image }}
steps:
- name: Install packages
run: ${{ inputs.package_installation_command }}
if: ${{ inputs.package_installation_command != '' }}
- name: Checkout source codes
uses: actions/checkout@v3
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY_PEM }}
known_hosts: unnecessary
if_key_exists: replace
- name: git clone through SSH
run: git clone git@github.com:shimataro/ssh-key-action.git tmp
key_if_exists_ignore-key_exists:
name: if_key_exists=ignore / key exists
runs-on: ${{ inputs.os }}
container: ${{ inputs.docker_image }}
steps:
- name: Install packages
run: ${{ inputs.package_installation_command }}
if: ${{ inputs.package_installation_command != '' }}
- name: Checkout source codes
uses: actions/checkout@v3
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY_PEM }}
known_hosts: unnecessary
- name: Install SSH key (does nothing)
uses: ./.
with:
key: "dummy" # ignored
known_hosts: unnecessary
if_key_exists: ignore
- name: git clone through SSH
run: git clone git@github.com:shimataro/ssh-key-action.git tmp
key_if_exists_ignore-key_doesnt_exist:
name: if_key_exists=ignore / key doesn't exist
runs-on: ${{ inputs.os }}
container: ${{ inputs.docker_image }}
steps:
- name: Install packages
run: ${{ inputs.package_installation_command }}
if: ${{ inputs.package_installation_command != '' }}
- name: Checkout source codes
uses: actions/checkout@v3
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY_PEM }}
known_hosts: unnecessary
if_key_exists: ignore
- name: git clone through SSH
run: git clone git@github.com:shimataro/ssh-key-action.git tmp
key_if_exists_fail-key_exists:
name: if_key_exists=fail / key exists
runs-on: ${{ inputs.os }}
container: ${{ inputs.docker_image }}
steps:
- name: Install packages
run: ${{ inputs.package_installation_command }}
if: ${{ inputs.package_installation_command != '' }}
- name: Checkout source codes
uses: actions/checkout@v3
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY_PEM }}
known_hosts: unnecessary
- name: Install SSH key (fails)
uses: ./.
with:
key: "dummy" # fails
known_hosts: unnecessary
if_key_exists: fail
continue-on-error: true
- name: git clone through SSH
run: git clone git@github.com:shimataro/ssh-key-action.git tmp
key_if_exists_fail-key_doesnt_exist:
name: if_key_exists=fail / key doesn't exist
runs-on: ${{ inputs.os }}
container: ${{ inputs.docker_image }}
steps:
- name: Install packages
run: ${{ inputs.package_installation_command }}
if: ${{ inputs.package_installation_command != '' }}
- name: Checkout source codes
uses: actions/checkout@v3
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY_PEM }}
known_hosts: unnecessary
if_key_exists: fail
- name: git clone through SSH
run: git clone git@github.com:shimataro/ssh-key-action.git tmp

View File

@ -0,0 +1,26 @@
# https://help.github.com/en/articles/workflow-syntax-for-github-actions
name: Docker container (Alpine Linux)
on:
- push
jobs:
verify:
name: Verify
strategy:
fail-fast: false
matrix:
os:
- ubuntu-20.04
- ubuntu-22.04
docker_image:
- alpine:3.10
- alpine:3.11
- alpine:3.12
- alpine:3.13
uses: "./.github/workflows/reusable-verify.yml"
with:
os: ${{ matrix.os }}
docker_image: ${{ matrix.docker_image }}
package_installation_command: apk add openssh-client git
secrets: inherit

View File

@ -0,0 +1,23 @@
# https://help.github.com/en/articles/workflow-syntax-for-github-actions
name: Docker container (CentOS)
on:
- push
jobs:
verify:
name: Verify
strategy:
fail-fast: false
matrix:
os:
- ubuntu-20.04
- ubuntu-22.04
docker_image:
- quay.io/centos/centos:stream8
uses: "./.github/workflows/reusable-verify.yml"
with:
os: ${{ matrix.os }}
docker_image: ${{ matrix.docker_image }}
package_installation_command: yum install -y git openssh-clients
secrets: inherit

View File

@ -0,0 +1,26 @@
# https://help.github.com/en/articles/workflow-syntax-for-github-actions
name: Docker container (Ubuntu)
on:
- push
jobs:
verify:
name: Verify
strategy:
fail-fast: false
matrix:
os:
- ubuntu-20.04
- ubuntu-22.04
docker_image:
- ubuntu:20.04
- ubuntu:22.04
uses: "./.github/workflows/reusable-verify.yml"
with:
os: ${{ matrix.os }}
docker_image: ${{ matrix.docker_image }}
package_installation_command: |
apt update
apt install -y openssh-client git
secrets: inherit

View File

@ -1,45 +0,0 @@
# https://help.github.com/en/articles/workflow-syntax-for-github-actions
name: macOS Catalina
on:
- push
- pull_request
jobs:
ssh:
name: Connect to github.com
runs-on: macos-10.15
steps:
- name: Checkout source codes
uses: actions/checkout@v2
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY }}
known_hosts: ${{ secrets.KNOWN_HOSTS }}
- name: print created files
run: ls -l ~/.ssh
- name: git clone through SSH
run: git clone git@github.com:shimataro/ssh-key-action.git tmp
ssh-with-name:
name: Connect to github.com with name and config
runs-on: macos-10.15
steps:
- name: Checkout source codes
uses: actions/checkout@v2
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY }}
known_hosts: ${{ secrets.KNOWN_HOSTS }}
name: ssh_key_name # optional
config: | # optional
Host github
Hostname github.com
User git
IdentityFile ~/.ssh/ssh_key_name
- name: print created files
run: ls -l ~/.ssh
- name: git clone through SSH
run: git clone github:shimataro/ssh-key-action.git tmp

19
.github/workflows/verify-on-macos.yml vendored Normal file
View File

@ -0,0 +1,19 @@
# https://help.github.com/en/articles/workflow-syntax-for-github-actions
name: macOS
on:
- push
jobs:
verify:
name: Verify
strategy:
fail-fast: false
matrix:
os:
- macos-11
- macos-12
uses: "./.github/workflows/reusable-verify.yml"
with:
os: ${{ matrix.os }}
secrets: inherit

View File

@ -1,45 +0,0 @@
# https://help.github.com/en/articles/workflow-syntax-for-github-actions
name: Ubuntu 16.04
on:
- push
- pull_request
jobs:
ssh:
name: Connect to github.com
runs-on: ubuntu-16.04
steps:
- name: Checkout source codes
uses: actions/checkout@v2
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY }}
known_hosts: ${{ secrets.KNOWN_HOSTS }}
- name: print created files
run: ls -l ~/.ssh
- name: git clone through SSH
run: git clone git@github.com:shimataro/ssh-key-action.git tmp
ssh-with-name:
name: Connect to github.com with name and config
runs-on: ubuntu-16.04
steps:
- name: Checkout source codes
uses: actions/checkout@v2
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY }}
known_hosts: ${{ secrets.KNOWN_HOSTS }}
name: ssh_key_name # optional
config: | # optional
Host github
Hostname github.com
User git
IdentityFile ~/.ssh/ssh_key_name
- name: print created files
run: ls -l ~/.ssh
- name: git clone through SSH
run: git clone github:shimataro/ssh-key-action.git tmp

View File

@ -1,45 +0,0 @@
# https://help.github.com/en/articles/workflow-syntax-for-github-actions
name: Ubuntu 18.04
on:
- push
- pull_request
jobs:
ssh:
name: Connect to github.com
runs-on: ubuntu-18.04
steps:
- name: Checkout source codes
uses: actions/checkout@v2
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY }}
known_hosts: ${{ secrets.KNOWN_HOSTS }}
- name: print created files
run: ls -l ~/.ssh
- name: git clone through SSH
run: git clone git@github.com:shimataro/ssh-key-action.git tmp
ssh-with-name:
name: Connect to github.com with name and config
runs-on: ubuntu-18.04
steps:
- name: Checkout source codes
uses: actions/checkout@v2
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY }}
known_hosts: ${{ secrets.KNOWN_HOSTS }}
name: ssh_key_name # optional
config: | # optional
Host github
Hostname github.com
User git
IdentityFile ~/.ssh/ssh_key_name
- name: print created files
run: ls -l ~/.ssh
- name: git clone through SSH
run: git clone github:shimataro/ssh-key-action.git tmp

View File

@ -1,45 +0,0 @@
# https://help.github.com/en/articles/workflow-syntax-for-github-actions
name: Ubuntu 20.04
on:
- push
- pull_request
jobs:
ssh:
name: Connect to github.com
runs-on: ubuntu-20.04
steps:
- name: Checkout source codes
uses: actions/checkout@v2
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY }}
known_hosts: ${{ secrets.KNOWN_HOSTS }}
- name: print created files
run: ls -l ~/.ssh
- name: git clone through SSH
run: git clone git@github.com:shimataro/ssh-key-action.git tmp
ssh-with-name:
name: Connect to github.com with name and config
runs-on: ubuntu-20.04
steps:
- name: Checkout source codes
uses: actions/checkout@v2
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY }}
known_hosts: ${{ secrets.KNOWN_HOSTS }}
name: ssh_key_name # optional
config: | # optional
Host github
Hostname github.com
User git
IdentityFile ~/.ssh/ssh_key_name
- name: print created files
run: ls -l ~/.ssh
- name: git clone through SSH
run: git clone github:shimataro/ssh-key-action.git tmp

19
.github/workflows/verify-on-ubuntu.yml vendored Normal file
View File

@ -0,0 +1,19 @@
# https://help.github.com/en/articles/workflow-syntax-for-github-actions
name: Ubuntu
on:
- push
jobs:
verify:
name: Verify
strategy:
fail-fast: false
matrix:
os:
- ubuntu-20.04
- ubuntu-22.04
uses: "./.github/workflows/reusable-verify.yml"
with:
os: ${{ matrix.os }}
secrets: inherit

View File

@ -1,45 +0,0 @@
# https://help.github.com/en/articles/workflow-syntax-for-github-actions
name: Windows Server 2019
on:
- push
- pull_request
jobs:
ssh:
name: Connect to github.com
runs-on: windows-2019
steps:
- name: Checkout source codes
uses: actions/checkout@v2
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY }}
known_hosts: ${{ secrets.KNOWN_HOSTS }}
- name: print created files
run: ls ~/.ssh
- name: git clone through SSH
run: git clone git@github.com:shimataro/ssh-key-action.git tmp
ssh-with-name:
name: Connect to github.com with name and config
runs-on: windows-2019
steps:
- name: Checkout source codes
uses: actions/checkout@v2
- name: Install SSH key
uses: ./.
with:
key: ${{ secrets.SSH_KEY }}
known_hosts: ${{ secrets.KNOWN_HOSTS }}
name: ssh_key_name # optional
config: | # optional
Host github
Hostname github.com
User git
IdentityFile ~/.ssh/ssh_key_name
- name: print created files
run: ls ~/.ssh
- name: git clone through SSH
run: git clone github:shimataro/ssh-key-action.git tmp

19
.github/workflows/verify-on-windows.yml vendored Normal file
View File

@ -0,0 +1,19 @@
# https://help.github.com/en/articles/workflow-syntax-for-github-actions
name: Windows
on:
- push
jobs:
verify:
name: Verify
strategy:
fail-fast: false
matrix:
os:
- windows-2019
- windows-2022
uses: "./.github/workflows/reusable-verify.yml"
with:
os: ${{ matrix.os }}
secrets: inherit

6
.gitignore vendored
View File

@ -12,3 +12,9 @@ Thumbs.db
# patch/merge
*.orig
*.rej
# IDE
/.idea/
# Node.js modules
/node_modules/

View File

@ -1,7 +1,7 @@
MD007: # ul-indent
indent: 4
MD013: # line-length
line_length: 255
line_length: 1024
MD024: # no-duplicate-heading
siblings_only: true
MD026: false # no-trailing-punctuation

View File

@ -7,6 +7,89 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased]
## [2.7.0] - 2024-02-11
### Others
* Update to Node.js v20 (thanks [@princemaple](https://github.com/princemaple))
* drop old containers; Ubuntu 16.04, and CentOS 7
## [2.6.1] - 2023-10-13
### Fixed
* JSON parse error on exit, if `if_key_exists`=`fail` and key exists
## [2.6.0] - 2023-10-11
### Others
* back up and restore files when exist (thanks [@bambeusz](https://github.com/bambeusz))
* remove `macos-10.15` and `ubuntu-18.04` virtual environment
## [2.5.1] - 2023-03-25
### Hotfix
* update github.com key: <https://github.blog/2023-03-23-we-updated-our-rsa-ssh-host-key/> (thanks [@phlax](https://github.com/phlax))
## [2.5.0] - 2022-12-24
### Added
* remove SSH directory at the end of workflow
## [2.4.0] - 2022-11-03
### Added
* always set server key of `github.com` to `known_hosts`
### Fixed
* usage of `rsync` in README
### Others
* add `windows-2022`, and `macos-11` (thanks [@ViacheslavKudinov](https://github.com/ViacheslavKudinov))
* add `macos-12`, `ubuntu-22.04`, and `CentOS 8 Stream (Docker container)`
* drop `ubuntu-16.04`, and `CentOS 8 (Docker container)`
* [update Node.js version to 16](https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/) (thanks [@duddu](https://github.com/duddu))
## [2.3.1] - 2021-08-01
### Security
* Fix [CVE-2021-33502](https://github.com/advisories/GHSA-px4h-xg32-q955)
### Others
* add `windows-2016` virtual environment
* [remove `ubuntu-16.04` virtual environment](https://github.blog/changelog/2021-04-29-github-actions-ubuntu-16-04-lts-virtual-environment-will-be-removed-on-september-20-2021/)
## [2.3.0] - 2021-03-21
### Added
* `if_key_exists` parameter
* `known_hosts: unnecessary`
* Support Alpine Linux Docker container
## [2.2.0] - 2021-02-27
### Added
* Support Ubuntu/CentOS Docker container (thanks [@kujaomega](https://github.com/kujaomega))
* Support PKCS8/RFC4716 formats (thanks [@tats-u](https://github.com/tats-u))
### Changed
* Bundle dependencies (thanks [@tats-u](https://github.com/tats-u))
### Fixed
* comments in README (thanks [@KimSoungRyoul](https://github.com/KimSoungRyoul))
## [2.1.0] - 2020-08-15
### Changed
@ -123,7 +206,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
* First release.
[Unreleased]: https://github.com/shimataro/ssh-key-action/compare/v2.1.0...HEAD
[Unreleased]: https://github.com/shimataro/ssh-key-action/compare/v2.7.0...HEAD
[2.7.0]: https://github.com/shimataro/ssh-key-action/compare/v2.6.1...v2.7.0
[2.6.1]: https://github.com/shimataro/ssh-key-action/compare/v2.6.0...v2.6.1
[2.6.0]: https://github.com/shimataro/ssh-key-action/compare/v2.5.1...v2.6.0
[2.5.1]: https://github.com/shimataro/ssh-key-action/compare/v2.5.0...v2.5.1
[2.5.0]: https://github.com/shimataro/ssh-key-action/compare/v2.4.0...v2.5.0
[2.4.0]: https://github.com/shimataro/ssh-key-action/compare/v2.3.1...v2.4.0
[2.3.1]: https://github.com/shimataro/ssh-key-action/compare/v2.3.0...v2.3.1
[2.3.0]: https://github.com/shimataro/ssh-key-action/compare/v2.2.0...v2.3.0
[2.2.0]: https://github.com/shimataro/ssh-key-action/compare/v2.1.0...v2.2.0
[2.1.0]: https://github.com/shimataro/ssh-key-action/compare/v2.0.3...v2.1.0
[2.0.3]: https://github.com/shimataro/ssh-key-action/compare/v2.0.2...v2.0.3
[2.0.2]: https://github.com/shimataro/ssh-key-action/compare/v2.0.1...v2.0.2

View File

@ -1,11 +1,12 @@
# Install SSH Key
[![Build][image-build]][link-build]
[![Windows Server 2019][image-verify-windows-2019]][link-verify-windows-2019]
[![macOS Catalina][image-verify-macos-1015]][link-verify-macos-1015]
[![Ubuntu 20.04][image-verify-ubuntu-2004]][link-verify-ubuntu-2004]
[![Ubuntu 18.04][image-verify-ubuntu-1804]][link-verify-ubuntu-1804]
[![Ubuntu 16.04][image-verify-ubuntu-1604]][link-verify-ubuntu-1604]
[![Windows][image-verify-windows]][link-verify-windows]
[![macOS][image-verify-macos]][link-verify-macos]
[![Ubuntu][image-verify-ubuntu]][link-verify-ubuntu]
[![Docker container (Ubuntu)][image-verify-docker-container-ubuntu]][link-verify-docker-container-ubuntu]
[![Docker container (CentOS)][image-verify-docker-container-centos]][link-verify-docker-container-centos]
[![Docker container (Alpine Linux)][image-verify-docker-container-alpine]][link-verify-docker-container-alpine]
[![Release][image-release]][link-release]
[![License][image-license]][link-license]
[![Stars][image-stars]][link-stars]
@ -14,16 +15,18 @@ This action installs SSH key in `~/.ssh`.
Useful for SCP, SFTP, and `rsync` over SSH in deployment script.
**Works on all [virtual environments](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/virtual-environments-for-github-hosted-runners#supported-runners-and-hardware-resources) --**
**Windows Server 2019, macOS Catalina, Ubuntu 20.04, Ubuntu 18.04, and Ubuntu 16.04.**
tested on:
* [all available virtual machines](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/virtual-environments-for-github-hosted-runners#supported-runners-and-hardware-resources) (Windows Server 2022/2019, macOS Monterey/Big Sur, and Ubuntu 22.04/20.04)
* [Docker container (Ubuntu)](https://hub.docker.com/_/ubuntu) / requires `openssh-client` package; `apt install -y openssh-client`
* [Docker container (CentOS)](https://quay.io/repository/centos/centos) / requires `openssh-clients` package; `yum install -y openssh-clients`
* [Docker container (Alpine Linux)](https://hub.docker.com/_/alpine) / requires `openssh-client` package; `apk add openssh-client`
## Usage
Add your SSH key to your product secrets by clicking `Settings` - `Secrets` - `Add a new secret` beforehand.
**NOTE:** OPENSSH format (key begins with `-----BEGIN OPENSSH PRIVATE KEY-----`) may not work due to OpenSSH version on VM.
Please use PEM format (begins with `-----BEGIN RSA PRIVATE KEY-----`) instead.
In order to convert your key inline to PEM format simply use `ssh-keygen -p -m PEM -f ~/.ssh/id_rsa`.
PEM(RSA), PKCS8, and RFC4716(OpenSSH) formats are OK.
```yaml
runs-on: ubuntu-latest
@ -35,18 +38,24 @@ steps:
name: id_rsa # optional
known_hosts: ${{ secrets.KNOWN_HOSTS }}
config: ${{ secrets.CONFIG }} # ssh_config; optional
- name: rsync over ssh
run: rsync ./foo/ user@remote:bar/
if_key_exists: fail # replace / ignore / fail; optional (defaults to fail)
- name: rsync over SSH
run: rsync -r ./foo/ user@remote:bar/
```
See [Workflow syntax for GitHub Actions](https://help.github.com/en/articles/workflow-syntax-for-github-actions) for details.
**NOTE:**
* Server key of `github.com` will be always set to `known_hosts`.
* SSH keys will be removed at the end of workflow.
### Install multiple keys
If you want to install multiple keys, call this action multiple times.
It is useful for port forwarding.
**NOTE:** When this action is called multiple times, **the contents of `known_hosts` and `config` will be appended**. `key` must be saved as different name, by using `name` option.
**NOTE:** When this action is called multiple times, **the contents of `known_hosts` and `config` will be appended**. `key` must be saved as different name, by using `name` option.
```yaml
runs-on: ubuntu-latest
@ -67,8 +76,8 @@ steps:
with:
key: ${{ secrets.SSH_KEY_OF_TARGET }}
name: id_rsa-target
known_hosts: ${{ secrets.KNOWN_HOSTS_OF_TARGET }} # will be appended!
config: | # will be appended!
known_hosts: ${{ secrets.KNOWN_HOSTS_OF_TARGET }} # will be appended to existing .ssh/known_hosts
config: | # will be appended to existing .ssh/config
Host target
HostName yyy.yyy.yyy.yyy
User user-of-target
@ -84,12 +93,17 @@ steps:
Check below:
* `Load key "/HOME/.ssh/id_rsa": invalid format`:
* OPENSSH format (key begins with `-----BEGIN OPENSSH PRIVATE KEY-----`) may not work.
* Use PEM format (begins with `-----BEGIN RSA PRIVATE KEY-----`). Convert it from OPENSSH format using `ssh-keygen -p -m PEM -f ~/.ssh/id_rsa`
* `Host key verification failed.`:
* Set `known_hosts` parameter correctly (use `ssh-keyscan` command).
### I want to replace/ignore key if exists.
Use `if_key_exists` parameter.
* `replace`: replaces key
* `ignore`: does nothing
* `fail`: fails (default)
### How do I use encrypted SSH key?
This action doesn't support encrypted key directly.
@ -105,7 +119,7 @@ Here are some solutions:
I recommend **rsync via bastion**.
```bash
rsync -e "ssh bastion ssh" ./foo/ target:bar/
rsync -r -e "ssh bastion ssh" ./foo/ target:bar/
```
It has some advantages over other methods:
@ -124,6 +138,18 @@ It has some advantages over other methods:
* And will be updated continuously.
* if security incident ―e.g., private key leaked― occurs, it's OK just to remove `authorized_keys` on bastion.
### I want to omit `known_hosts`.
First of all, you have to understand that it is NOT secure to SSH with no `known_hosts` and using `StrictHostKeyChecking=no` option.
Why do you want to omit it?
If the reason is **"I'm not understanding about the function of `known_hosts`"** or **"It's bother to fetch server key"**, you should not omit.
If **"It is hard to prefetch server key because the server will be created dynamically"**, you can use bastion server.
**"`known_hosts` is unnecessary because I'm using secure method for SSH, such as SSHFP and signed server key."** — OK, here is a special value to omit `known_hosts`.
You should use it ONLY IF you are using secure methods...
It is `known_hosts: unnecessary`.
## License
The scripts and documentation in this project are released under the [MIT License](LICENSE)
@ -133,17 +159,19 @@ The scripts and documentation in this project are released under the [MIT Licens
See [CHANGELOG.md](CHANGELOG.md).
[image-build]: https://github.com/shimataro/ssh-key-action/workflows/Build/badge.svg?event=push&branch=v2
[link-build]: https://github.com/shimataro/ssh-key-action/actions?query=workflow%3ABuild
[image-verify-windows-2019]: https://github.com/shimataro/ssh-key-action/workflows/Windows%20Server%202019/badge.svg?event=push&branch=v2
[link-verify-windows-2019]: https://github.com/shimataro/ssh-key-action/actions?query=workflow%3A%22Windows+Server+2019%22
[image-verify-macos-1015]: https://github.com/shimataro/ssh-key-action/workflows/macOS%20Catalina/badge.svg?event=push&branch=v2
[link-verify-macos-1015]: https://github.com/shimataro/ssh-key-action/actions?query=workflow%3A%22macOS+Catalina%22
[image-verify-ubuntu-2004]: https://github.com/shimataro/ssh-key-action/workflows/Ubuntu%2020.04/badge.svg?event=push&branch=v2
[link-verify-ubuntu-2004]: https://github.com/shimataro/ssh-key-action/actions?query=workflow%3A%22Ubuntu+20.04%22
[image-verify-ubuntu-1804]: https://github.com/shimataro/ssh-key-action/workflows/Ubuntu%2018.04/badge.svg?event=push&branch=v2
[link-verify-ubuntu-1804]: https://github.com/shimataro/ssh-key-action/actions?query=workflow%3A%22Ubuntu+18.04%22
[image-verify-ubuntu-1604]: https://github.com/shimataro/ssh-key-action/workflows/Ubuntu%2016.04/badge.svg?event=push&branch=v2
[link-verify-ubuntu-1604]: https://github.com/shimataro/ssh-key-action/actions?query=workflow%3A%22Ubuntu+16.04%22
[link-build]: https://github.com/shimataro/ssh-key-action/actions/workflows/build.yml
[image-verify-windows]: https://github.com/shimataro/ssh-key-action/workflows/Windows/badge.svg?event=push&branch=v2
[link-verify-windows]: https://github.com/shimataro/ssh-key-action/actions/workflows/verify-on-windows.yml
[image-verify-macos]: https://github.com/shimataro/ssh-key-action/workflows/macOS/badge.svg?event=push&branch=v2
[link-verify-macos]: https://github.com/shimataro/ssh-key-action/actions/workflows/verify-on-macos.yml
[image-verify-ubuntu]: https://github.com/shimataro/ssh-key-action/workflows/Ubuntu/badge.svg?event=push&branch=v2
[link-verify-ubuntu]: https://github.com/shimataro/ssh-key-action/actions/workflows/verify-on-ubuntu.yml
[image-verify-docker-container-ubuntu]: https://github.com/shimataro/ssh-key-action/actions/workflows/verify-on-container-ubuntu.yml/badge.svg?event=push&branch=v2
[link-verify-docker-container-ubuntu]: https://github.com/shimataro/ssh-key-action/actions/workflows/verify-on-container-ubuntu.yml
[image-verify-docker-container-centos]: https://github.com/shimataro/ssh-key-action/actions/workflows/verify-on-container-centos.yml/badge.svg?event=push&branch=v2
[link-verify-docker-container-centos]: https://github.com/shimataro/ssh-key-action/actions/workflows/verify-on-container-centos.yml
[image-verify-docker-container-alpine]: https://github.com/shimataro/ssh-key-action/actions/workflows/verify-on-container-alpine.yml/badge.svg?event=push&branch=v2
[link-verify-docker-container-alpine]: https://github.com/shimataro/ssh-key-action/actions/workflows/verify-on-container-alpine.yml
[image-release]: https://img.shields.io/github/release/shimataro/ssh-key-action.svg
[link-release]: https://github.com/shimataro/ssh-key-action/releases
[image-license]: https://img.shields.io/github/license/shimataro/ssh-key-action.svg

View File

@ -21,6 +21,11 @@ inputs:
description: "SSH config"
required: false
default: ""
if_key_exists:
description: "replace / ignore / fail"
required: false
default: "fail"
runs:
using: "node12"
main: "lib/main.js"
using: "node20"
main: "./dist/main.js"
post: "./dist/post.js"

74
dist/main.js vendored Normal file

File diff suppressed because one or more lines are too long

7
dist/main.js.map vendored Normal file

File diff suppressed because one or more lines are too long

69
dist/post.js vendored Normal file

File diff suppressed because one or more lines are too long

7
dist/post.js.map vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,125 +0,0 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const core = __importStar(require("@actions/core"));
/**
* main function
*/
function main() {
try {
const files = [
{
name: core.getInput("name"),
contents: core.getInput("key", {
required: true,
}),
options: {
mode: 0o400,
flag: "ax",
},
},
{
name: "known_hosts",
contents: insertLf(core.getInput("known_hosts", {
required: true,
})),
options: {
mode: 0o644,
flag: "a",
},
},
{
name: "config",
contents: insertLf(core.getInput("config")),
options: {
mode: 0o644,
flag: "a",
},
},
];
// create ".ssh" directory
const home = getHomeDirectory();
const dirName = path_1.default.resolve(home, ".ssh");
fs_1.default.mkdirSync(dirName, {
recursive: true,
mode: 0o700,
});
// create files
for (const file of files) {
const fileName = path_1.default.join(dirName, file.name);
fs_1.default.writeFileSync(fileName, file.contents, file.options);
}
console.log(`SSH key has been stored to ${dirName} successfully.`);
}
catch (err) {
core.setFailed(err.message);
}
}
/**
* get home directory
* @returns home directory
*/
function getHomeDirectory() {
const homeEnv = getHomeEnv();
const home = process.env[homeEnv];
if (home === undefined) {
throw Error(`${homeEnv} is not defined`);
}
return home;
}
/**
* get HOME environment name
* @returns HOME environment name
*/
function getHomeEnv() {
if (process.platform === "win32") {
// Windows
return "USERPROFILE";
}
// macOS / Linux
return "HOME";
}
/**
* prepend/append LF to value if not empty
* @param value the value to prepend LF
* @returns prepended value
*/
function insertLf(value) {
let affectedValue = value;
if (value.length === 0) {
// do nothing if empty
return "";
}
if (!affectedValue.startsWith("\n")) {
affectedValue = `\n${affectedValue}`;
}
if (!affectedValue.endsWith("\n")) {
affectedValue = `${affectedValue}\n`;
}
return affectedValue;
}
main();
//# sourceMappingURL=main.js.map

View File

@ -1 +0,0 @@
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAAoB;AACpB,gDAAwB;AAExB,oDAAsC;AAStC;;GAEG;AACH,SAAS,IAAI;IAEZ,IACA;QACC,MAAM,KAAK,GAAe;YACzB;gBACC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE;oBAC9B,QAAQ,EAAE,IAAI;iBACd,CAAC;gBACF,OAAO,EAAE;oBACR,IAAI,EAAE,KAAK;oBACX,IAAI,EAAE,IAAI;iBACV;aACD;YACD;gBACC,IAAI,EAAE,aAAa;gBACnB,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE;oBAC/C,QAAQ,EAAE,IAAI;iBACd,CAAC,CAAC;gBACH,OAAO,EAAE;oBACR,IAAI,EAAE,KAAK;oBACX,IAAI,EAAE,GAAG;iBACT;aACD;YACD;gBACC,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAC3C,OAAO,EAAE;oBACR,IAAI,EAAE,KAAK;oBACX,IAAI,EAAE,GAAG;iBACT;aACD;SACD,CAAC;QAEF,0BAA0B;QAC1B,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,cAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC3C,YAAE,CAAC,SAAS,CAAC,OAAO,EAAE;YACrB,SAAS,EAAE,IAAI;YACf,IAAI,EAAE,KAAK;SACX,CAAC,CAAC;QAEH,eAAe;QACf,KAAI,MAAM,IAAI,IAAI,KAAK,EACvB;YACC,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/C,YAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;SACxD;QAED,OAAO,CAAC,GAAG,CAAC,8BAA8B,OAAO,gBAAgB,CAAC,CAAC;KACnE;IACD,OAAM,GAAG,EACT;QACC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;KAC5B;AACF,CAAC;AAED;;;GAGG;AACH,SAAS,gBAAgB;IAExB,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAClC,IAAG,IAAI,KAAK,SAAS,EACrB;QACC,MAAM,KAAK,CAAC,GAAG,OAAO,iBAAiB,CAAC,CAAC;KACzC;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,SAAS,UAAU;IAElB,IAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,EAC/B;QACC,UAAU;QACV,OAAO,aAAa,CAAC;KACrB;IAED,gBAAgB;IAChB,OAAO,MAAM,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,SAAS,QAAQ,CAAC,KAAa;IAE9B,IAAI,aAAa,GAAG,KAAK,CAAC;IAE1B,IAAG,KAAK,CAAC,MAAM,KAAK,CAAC,EACrB;QACC,sBAAsB;QACtB,OAAO,EAAE,CAAC;KACV;IACD,IAAG,CAAC,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,EAClC;QACC,aAAa,GAAG,KAAK,aAAa,EAAE,CAAC;KACrC;IACD,IAAG,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,EAChC;QACC,aAAa,GAAG,GAAG,aAAa,IAAI,CAAC;KACrC;IAED,OAAO,aAAa,CAAC;AACtB,CAAC;AAED,IAAI,EAAE,CAAC"}

146
node_modules/@actions/core/README.md generated vendored
View File

@ -1,146 +0,0 @@
# `@actions/core`
> Core functions for setting results, logging, registering secrets and exporting variables across actions
## Usage
### Import the package
```js
// javascript
const core = require('@actions/core');
// typescript
import * as core from '@actions/core';
```
#### Inputs/Outputs
Action inputs can be read with `getInput`. Outputs can be set with `setOutput` which makes them available to be mapped into inputs of other actions to ensure they are decoupled.
```js
const myInput = core.getInput('inputName', { required: true });
core.setOutput('outputKey', 'outputVal');
```
#### Exporting variables
Since each step runs in a separate process, you can use `exportVariable` to add it to this step and future steps environment blocks.
```js
core.exportVariable('envVar', 'Val');
```
#### Setting a secret
Setting a secret registers the secret with the runner to ensure it is masked in logs.
```js
core.setSecret('myPassword');
```
#### PATH Manipulation
To make a tool's path available in the path for the remainder of the job (without altering the machine or containers state), use `addPath`. The runner will prepend the path given to the jobs PATH.
```js
core.addPath('/path/to/mytool');
```
#### Exit codes
You should use this library to set the failing exit code for your action. If status is not set and the script runs to completion, that will lead to a success.
```js
const core = require('@actions/core');
try {
// Do stuff
}
catch (err) {
// setFailed logs the message and sets a failing exit code
core.setFailed(`Action failed with error ${err}`);
}
Note that `setNeutral` is not yet implemented in actions V2 but equivalent functionality is being planned.
```
#### Logging
Finally, this library provides some utilities for logging. Note that debug logging is hidden from the logs by default. This behavior can be toggled by enabling the [Step Debug Logs](../../docs/action-debugging.md#step-debug-logs).
```js
const core = require('@actions/core');
const myInput = core.getInput('input');
try {
core.debug('Inside try block');
if (!myInput) {
core.warning('myInput was not set');
}
if (core.isDebug()) {
// curl -v https://github.com
} else {
// curl https://github.com
}
// Do stuff
}
catch (err) {
core.error(`Error ${err}, action may still succeed though`);
}
```
This library can also wrap chunks of output in foldable groups.
```js
const core = require('@actions/core')
// Manually wrap output
core.startGroup('Do some function')
doSomeFunction()
core.endGroup()
// Wrap an asynchronous function call
const result = await core.group('Do something async', async () => {
const response = await doSomeHTTPRequest()
return response
})
```
#### Action state
You can use this library to save state and get state for sharing information between a given wrapper action:
**action.yml**
```yaml
name: 'Wrapper action sample'
inputs:
name:
default: 'GitHub'
runs:
using: 'node12'
main: 'main.js'
post: 'cleanup.js'
```
In action's `main.js`:
```js
const core = require('@actions/core');
core.saveState("pidToKill", 12345);
```
In action's `cleanup.js`:
```js
const core = require('@actions/core');
var pid = core.getState("pidToKill");
process.kill(pid);
```

View File

@ -1,21 +0,0 @@
interface CommandProperties {
[key: string]: any;
}
/**
* Commands
*
* Command Format:
* ::name key=value,key=value::message
*
* Examples:
* ::warning::This is the message
* ::set-env name=MY_VAR::some value
*/
export declare function issueCommand(command: string, properties: CommandProperties, message: any): void;
export declare function issue(name: string, message?: string): void;
/**
* Sanitizes an input into a string so it can be passed into issueCommand safely
* @param input input to sanitize into a string
*/
export declare function toCommandValue(input: any): string;
export {};

View File

@ -1,92 +0,0 @@
"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const os = __importStar(require("os"));
/**
* Commands
*
* Command Format:
* ::name key=value,key=value::message
*
* Examples:
* ::warning::This is the message
* ::set-env name=MY_VAR::some value
*/
function issueCommand(command, properties, message) {
const cmd = new Command(command, properties, message);
process.stdout.write(cmd.toString() + os.EOL);
}
exports.issueCommand = issueCommand;
function issue(name, message = '') {
issueCommand(name, {}, message);
}
exports.issue = issue;
const CMD_STRING = '::';
class Command {
constructor(command, properties, message) {
if (!command) {
command = 'missing.command';
}
this.command = command;
this.properties = properties;
this.message = message;
}
toString() {
let cmdStr = CMD_STRING + this.command;
if (this.properties && Object.keys(this.properties).length > 0) {
cmdStr += ' ';
let first = true;
for (const key in this.properties) {
if (this.properties.hasOwnProperty(key)) {
const val = this.properties[key];
if (val) {
if (first) {
first = false;
}
else {
cmdStr += ',';
}
cmdStr += `${key}=${escapeProperty(val)}`;
}
}
}
}
cmdStr += `${CMD_STRING}${escapeData(this.message)}`;
return cmdStr;
}
}
/**
* Sanitizes an input into a string so it can be passed into issueCommand safely
* @param input input to sanitize into a string
*/
function toCommandValue(input) {
if (input === null || input === undefined) {
return '';
}
else if (typeof input === 'string' || input instanceof String) {
return input;
}
return JSON.stringify(input);
}
exports.toCommandValue = toCommandValue;
function escapeData(s) {
return toCommandValue(s)
.replace(/%/g, '%25')
.replace(/\r/g, '%0D')
.replace(/\n/g, '%0A');
}
function escapeProperty(s) {
return toCommandValue(s)
.replace(/%/g, '%25')
.replace(/\r/g, '%0D')
.replace(/\n/g, '%0A')
.replace(/:/g, '%3A')
.replace(/,/g, '%2C');
}
//# sourceMappingURL=command.js.map

View File

@ -1 +0,0 @@
{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"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"}

View File

@ -1,122 +0,0 @@
/**
* Interface for getInput options
*/
export interface InputOptions {
/** Optional. Whether the input is required. If required and not present, will throw. Defaults to false */
required?: boolean;
}
/**
* The code to exit an action
*/
export declare enum ExitCode {
/**
* A code indicating that the action was successful
*/
Success = 0,
/**
* A code indicating that the action was a failure
*/
Failure = 1
}
/**
* Sets env variable for this action and future actions in the job
* @param name the name of the variable to set
* @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify
*/
export declare function exportVariable(name: string, val: any): void;
/**
* Registers a secret which will get masked from logs
* @param secret value of the secret
*/
export declare function setSecret(secret: string): void;
/**
* Prepends inputPath to the PATH (for this action and future actions)
* @param inputPath
*/
export declare function addPath(inputPath: string): void;
/**
* Gets the value of an input. The value is also trimmed.
*
* @param name name of the input to get
* @param options optional. See InputOptions.
* @returns string
*/
export declare function getInput(name: string, options?: InputOptions): string;
/**
* Sets the value of an output.
*
* @param name name of the output to set
* @param value value to store. Non-string values will be converted to a string via JSON.stringify
*/
export declare function setOutput(name: string, value: any): void;
/**
* Enables or disables the echoing of commands into stdout for the rest of the step.
* Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.
*
*/
export declare function setCommandEcho(enabled: boolean): void;
/**
* Sets the action status to failed.
* When the action exits it will be with an exit code of 1
* @param message add error issue message
*/
export declare function setFailed(message: string | Error): void;
/**
* Gets whether Actions Step Debug is on or not
*/
export declare function isDebug(): boolean;
/**
* Writes debug message to user log
* @param message debug message
*/
export declare function debug(message: string): void;
/**
* Adds an error issue
* @param message error issue message. Errors will be converted to string via toString()
*/
export declare function error(message: string | Error): void;
/**
* Adds an warning issue
* @param message warning issue message. Errors will be converted to string via toString()
*/
export declare function warning(message: string | Error): void;
/**
* Writes info to log with console.log.
* @param message info message
*/
export declare function info(message: string): void;
/**
* Begin an output group.
*
* Output until the next `groupEnd` will be foldable in this group
*
* @param name The name of the output group
*/
export declare function startGroup(name: string): void;
/**
* End an output group.
*/
export declare function endGroup(): void;
/**
* Wrap an asynchronous function call in a group.
*
* Returns the same type as the function itself.
*
* @param name The name of the group
* @param fn The function to wrap in the group
*/
export declare function group<T>(name: string, fn: () => Promise<T>): Promise<T>;
/**
* Saves state for current action, the state can only be retrieved by this action's post job execution.
*
* @param name name of the state to store
* @param value value to store. Non-string values will be converted to a string via JSON.stringify
*/
export declare function saveState(name: string, value: any): void;
/**
* Gets the value of an state set by this action's main execution.
*
* @param name name of the state to get
* @returns string
*/
export declare function getState(name: string): string;

View File

@ -1,222 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const command_1 = require("./command");
const os = __importStar(require("os"));
const path = __importStar(require("path"));
/**
* The code to exit an action
*/
var ExitCode;
(function (ExitCode) {
/**
* A code indicating that the action was successful
*/
ExitCode[ExitCode["Success"] = 0] = "Success";
/**
* A code indicating that the action was a failure
*/
ExitCode[ExitCode["Failure"] = 1] = "Failure";
})(ExitCode = exports.ExitCode || (exports.ExitCode = {}));
//-----------------------------------------------------------------------
// Variables
//-----------------------------------------------------------------------
/**
* Sets env variable for this action and future actions in the job
* @param name the name of the variable to set
* @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function exportVariable(name, val) {
const convertedVal = command_1.toCommandValue(val);
process.env[name] = convertedVal;
command_1.issueCommand('set-env', { name }, convertedVal);
}
exports.exportVariable = exportVariable;
/**
* Registers a secret which will get masked from logs
* @param secret value of the secret
*/
function setSecret(secret) {
command_1.issueCommand('add-mask', {}, secret);
}
exports.setSecret = setSecret;
/**
* Prepends inputPath to the PATH (for this action and future actions)
* @param inputPath
*/
function addPath(inputPath) {
command_1.issueCommand('add-path', {}, inputPath);
process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;
}
exports.addPath = addPath;
/**
* Gets the value of an input. The value is also trimmed.
*
* @param name name of the input to get
* @param options optional. See InputOptions.
* @returns string
*/
function getInput(name, options) {
const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || '';
if (options && options.required && !val) {
throw new Error(`Input required and not supplied: ${name}`);
}
return val.trim();
}
exports.getInput = getInput;
/**
* Sets the value of an output.
*
* @param name name of the output to set
* @param value value to store. Non-string values will be converted to a string via JSON.stringify
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function setOutput(name, value) {
command_1.issueCommand('set-output', { name }, value);
}
exports.setOutput = setOutput;
/**
* Enables or disables the echoing of commands into stdout for the rest of the step.
* Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.
*
*/
function setCommandEcho(enabled) {
command_1.issue('echo', enabled ? 'on' : 'off');
}
exports.setCommandEcho = setCommandEcho;
//-----------------------------------------------------------------------
// Results
//-----------------------------------------------------------------------
/**
* Sets the action status to failed.
* When the action exits it will be with an exit code of 1
* @param message add error issue message
*/
function setFailed(message) {
process.exitCode = ExitCode.Failure;
error(message);
}
exports.setFailed = setFailed;
//-----------------------------------------------------------------------
// Logging Commands
//-----------------------------------------------------------------------
/**
* Gets whether Actions Step Debug is on or not
*/
function isDebug() {
return process.env['RUNNER_DEBUG'] === '1';
}
exports.isDebug = isDebug;
/**
* Writes debug message to user log
* @param message debug message
*/
function debug(message) {
command_1.issueCommand('debug', {}, message);
}
exports.debug = debug;
/**
* Adds an error issue
* @param message error issue message. Errors will be converted to string via toString()
*/
function error(message) {
command_1.issue('error', message instanceof Error ? message.toString() : message);
}
exports.error = error;
/**
* Adds an warning issue
* @param message warning issue message. Errors will be converted to string via toString()
*/
function warning(message) {
command_1.issue('warning', message instanceof Error ? message.toString() : message);
}
exports.warning = warning;
/**
* Writes info to log with console.log.
* @param message info message
*/
function info(message) {
process.stdout.write(message + os.EOL);
}
exports.info = info;
/**
* Begin an output group.
*
* Output until the next `groupEnd` will be foldable in this group
*
* @param name The name of the output group
*/
function startGroup(name) {
command_1.issue('group', name);
}
exports.startGroup = startGroup;
/**
* End an output group.
*/
function endGroup() {
command_1.issue('endgroup');
}
exports.endGroup = endGroup;
/**
* Wrap an asynchronous function call in a group.
*
* Returns the same type as the function itself.
*
* @param name The name of the group
* @param fn The function to wrap in the group
*/
function group(name, fn) {
return __awaiter(this, void 0, void 0, function* () {
startGroup(name);
let result;
try {
result = yield fn();
}
finally {
endGroup();
}
return result;
});
}
exports.group = group;
//-----------------------------------------------------------------------
// Wrapper action state
//-----------------------------------------------------------------------
/**
* Saves state for current action, the state can only be retrieved by this action's post job execution.
*
* @param name name of the state to store
* @param value value to store. Non-string values will be converted to a string via JSON.stringify
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function saveState(name, value) {
command_1.issueCommand('save-state', { name }, value);
}
exports.saveState = saveState;
/**
* Gets the value of an state set by this action's main execution.
*
* @param name name of the state to get
* @returns string
*/
function getState(name) {
return process.env[`STATE_${name}`] || '';
}
exports.getState = getState;
//# sourceMappingURL=core.js.map

View File

@ -1 +0,0 @@
{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}

View File

@ -1,44 +0,0 @@
{
"name": "@actions/core",
"version": "1.2.4",
"description": "Actions core lib",
"keywords": [
"github",
"actions",
"core"
],
"homepage": "https://github.com/actions/toolkit/tree/master/packages/core",
"license": "MIT",
"main": "lib/core.js",
"types": "lib/core.d.ts",
"directories": {
"lib": "lib",
"test": "__tests__"
},
"files": [
"lib"
],
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/actions/toolkit.git",
"directory": "packages/core"
},
"scripts": {
"audit-moderate": "npm install && npm audit --audit-level=moderate",
"test": "echo \"Error: run tests from root\" && exit 1",
"tsc": "tsc"
},
"bugs": {
"url": "https://github.com/actions/toolkit/issues"
},
"devDependencies": {
"@types/node": "^12.0.2"
}
,"_resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.4.tgz"
,"_integrity": "sha512-YJCEq8BE3CdN8+7HPZ/4DxJjk/OkZV2FFIf+DlZTC/4iBlzYCD5yjRR6eiOS5llO11zbRltIRuKAjMKaWTE6cg=="
,"_from": "@actions/core@1.2.4"
}

12732
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,19 @@
{
"name": "install-ssh-key",
"version": "2.1.0",
"version": "2.7.0",
"private": true,
"description": "Install SSH key in .ssh",
"main": "lib/main.js",
"main": "./dist/main.js",
"engines": {
"node": ">=8.0.0",
"npm": ">=5.7.0"
},
"scripts": {
"build": "tsc",
"build": "esbuild ./src/main.ts ./src/post.ts --bundle --platform=node --minify --sourcemap --outdir=./dist",
"check-updates": "ncu",
"lint": "run-p lint:*",
"lint:ts": "eslint ./src --ext .ts",
"lint:es": "eslint ./src --ext .ts",
"lint:ts": "tsc --noEmit ./src/main.ts ./src/post.ts",
"lint:md": "markdownlint . --ignore node_modules --ignore examples",
"lint:yaml": "yamllint **/{,.}*.{yml,yaml} --ignore=node_modules/**",
"verify": "run-p lint"
@ -30,18 +31,17 @@
],
"author": "shimataro",
"license": "MIT",
"dependencies": {
"@actions/core": "1.2.4"
},
"devDependencies": {
"@types/node": "14.0.27",
"@typescript-eslint/eslint-plugin": "3.9.0",
"@typescript-eslint/parser": "3.9.0",
"eslint": "7.7.0",
"markdownlint-cli": "0.23.2",
"npm-check-updates": "7.1.1",
"@actions/core": "1.10.1",
"@types/node": "20.11.17",
"@typescript-eslint/eslint-plugin": "6.21.0",
"@typescript-eslint/parser": "6.21.0",
"esbuild": "0.20.0",
"eslint": "8.56.0",
"markdownlint-cli": "0.39.0",
"npm-check-updates": "16.14.15",
"npm-run-all": "4.1.5",
"typescript": "3.9.7",
"yaml-lint": "1.2.4"
"typescript": "5.3.3",
"yaml-lint": "1.7.0"
}
}

View File

@ -1,136 +0,0 @@
#!/bin/bash
# requires following packages:
# - git; I believe you have already installed.
# - sed; GNU sed is preferred. POSIX sed may not work.
# - perl; Already installed on most of unix system.
set -e
BASE_BRANCH="develop"
PACKAGE_NAME="ssh-key-action"
URL_PRODUCT="https://github.com/shimataro/${PACKAGE_NAME}"
URL_REPOSITORY="${URL_PRODUCT}.git"
URL_COMPARE="${URL_PRODUCT}/compare"
URL_RELEASE="${URL_PRODUCT}/releases/new"
COLOR_ERROR="\e[1;41m"
COLOR_SECTION="\e[1;34m"
COLOR_COMMAND_NAME="\e[1;34m"
COLOR_OPTION="\e[4;36m"
COLOR_COMMAND="\e[4m"
COLOR_FILE="\e[1;34m"
COLOR_BRANCH="\e[1;31m"
COLOR_INPUT="\e[1;31m"
COLOR_SELECT="\e[1;32m"
COLOR_RESET="\e[m"
function main() {
cd $(dirname ${0})/..
if [ $# -lt 1 ]; then
usage
fi
local VERSION=$1
local BRANCH="release/v${VERSION}"
local TAG="v${VERSION}"
check_version_format ${VERSION}
check_current_branch
create_branch ${BRANCH}
./scripts/prepare-release.sh ${VERSION}
finish ${VERSION} ${BRANCH} ${TAG}
}
function usage() {
local COMMAND=`basename ${0}`
echo -e "${COLOR_SECTION}NAME${COLOR_RESET}
${COMMAND} - Create a branch and prepare for new release
${COLOR_SECTION}SYNOPSIS${COLOR_RESET}
${COLOR_COMMAND_NAME}${COMMAND}${COLOR_RESET} <${COLOR_OPTION}new-version${COLOR_RESET}>
${COLOR_SECTION}DESCRIPTION${COLOR_RESET}
This command:
- creates a new branch for release
- updates ${COLOR_FILE}CHANGELOG.md${COLOR_RESET}
- updates package version in ${COLOR_FILE}package.json${COLOR_RESET}
- updates dependencies version in ${COLOR_FILE}package.json${COLOR_RESET}
- verifies
- ...and commits!
${COLOR_OPTION}new-version${COLOR_RESET} must follow \"Semantic Versioning\" <https://semver.org/>.
"
exit 1
}
function check_version_format() {
if [[ $1 =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then
return
fi
echo -e "${COLOR_ERROR}ERROR:${COLOR_RESET} Follow \"Semantic Versioning\" <https://semver.org/> for new version.
" >&2
exit 2
}
function check_current_branch() {
local CURRENT_BRANCH=`git rev-parse --abbrev-ref HEAD`
if [ ${CURRENT_BRANCH} = ${BASE_BRANCH} ]; then
return
fi
echo -e "${COLOR_ERROR}ERROR:${COLOR_RESET} Work on ${COLOR_BRANCH}${BASE_BRANCH}${COLOR_RESET} branch
${COLOR_COMMAND}git checkout ${BASE_BRANCH}${COLOR_RESET}
" >&2
exit 2
}
function create_branch() {
local BRANCH=$1
git checkout -b ${BRANCH} ${BASE_BRANCH}
}
function finish() {
local VERSION=$1
local BRANCH=$2
local TAG=$3
local TARGET_BRANCH="v${VERSION%%[!0-9]*}"
local UPSTREAM="origin"
local CHANGELOG=$(git diff ${UPSTREAM}/${TARGET_BRANCH} ${BRANCH} CHANGELOG.md | sed -e "/^[^+]/d" -e "s/^\+\(.*\)$/\1/" -e "/^## /d" -e "/^\+/d" -e "/^\[/d" -e "s/\s/%20/g" -e "s/#/%23/g" -e 's/\n//g' | perl -pe "s/\n/%0A/g" | perl -pe "s/^(%0A)+//" | perl -pe "s/(%0A)+$//")
echo -e "
Branch ${COLOR_BRANCH}${BRANCH}${COLOR_RESET} has been created.
Remaining processes are...
1. Make sure all changes are correct
${COLOR_COMMAND}git diff ${BASE_BRANCH} ${BRANCH}${COLOR_RESET}
2. Push to remote ${UPSTREAM}
${COLOR_COMMAND}git push --set-upstream ${UPSTREAM} ${BRANCH}${COLOR_RESET}
3. Create a pull-request: ${COLOR_BRANCH}${BRANCH}${COLOR_RESET} to ${COLOR_BRANCH}${BASE_BRANCH}${COLOR_RESET}
${URL_COMPARE}/${BASE_BRANCH}...${BRANCH}?expand=1
select ${COLOR_SELECT}Squash and merge${COLOR_RESET}
4. Create a pull-request: ${COLOR_BRANCH}${BASE_BRANCH}${COLOR_RESET} to ${COLOR_BRANCH}${TARGET_BRANCH}${COLOR_RESET}
${URL_COMPARE}/${TARGET_BRANCH}...${BASE_BRANCH}?expand=1&title=version%20${VERSION}&body=${CHANGELOG}
select ${COLOR_SELECT}Create a merge commit${COLOR_RESET}
5. Create a new release
${URL_RELEASE}?tag=${TAG}&target=${TARGET_BRANCH}&title=${PACKAGE_NAME}%20${VERSION}%20released&body=${CHANGELOG}
Tag version: ${COLOR_INPUT}${TAG}${COLOR_RESET}
Target: ${COLOR_INPUT}${TARGET_BRANCH}${COLOR_RESET}
Release title: ${COLOR_INPUT}${PACKAGE_NAME} ${VERSION} released${COLOR_RESET}
Description this release: (copy and paste CHANGELOG.md)
6. Post processing
${COLOR_COMMAND}git checkout ${BASE_BRANCH}${COLOR_RESET}
${COLOR_COMMAND}git pull${COLOR_RESET}
${COLOR_COMMAND}git fetch -p${COLOR_RESET}
${COLOR_COMMAND}git branch -D ${BRANCH}${COLOR_RESET}
That's all!
"
}
main "$@"

View File

@ -1,41 +1,59 @@
#!/bin/bash
# requires following packages:
# - git; I believe it's already installed.
# - sed; GNU sed is preferred. POSIX sed may not work.
# requires following programs:
# - git; I believe you have already installed.
# - sed; Both GNU sed and POSIX sed will work.
set -eu
set -e
GITHUB_BASE="https://github.com"
GITHUB_USER="shimataro"
GITHUB_REPO="ssh-key-action"
COLOR_ERROR="\e[1;41m"
COLOR_SECTION="\e[1;34m"
COLOR_COMMAND_NAME="\e[1;34m"
COLOR_OPTION="\e[4;36m"
COLOR_COMMAND="\e[4m"
COLOR_FILE="\e[1;34m"
COLOR_BRANCH="\e[1;31m"
COLOR_INPUT="\e[1;31m"
COLOR_SELECT="\e[1;32m"
COLOR_RESET="\e[m"
UPSTREAM="origin"
COLOR_ERROR="\033[1;41m"
COLOR_SECTION="\033[1;34m"
COLOR_COMMAND_NAME="\033[1;34m"
COLOR_OPTION="\033[4;36m"
COLOR_COMMAND="\033[4m"
COLOR_FILE="\033[1;34m"
COLOR_BRANCH="\033[1;31m"
COLOR_INPUT="\033[1;31m"
COLOR_SELECT="\033[1;32m"
COLOR_RESET="\033[m"
URL_PRODUCT="${GITHUB_BASE}/${GITHUB_USER}/${GITHUB_REPO}"
URL_REPOSITORY="${URL_PRODUCT}.git"
URL_COMPARE="${URL_PRODUCT}/compare"
URL_RELEASE="${URL_PRODUCT}/releases/new"
function main() {
if [ $# -lt 1 ]; then
cd $(dirname ${0})/..
if [[ $# -lt 1 ]]; then
usage
fi
cd $(dirname ${0})/..
local NEW_VERSION=$1
local CURRENT_VERSION=$(
node -e 'console.log(JSON.parse(require("fs").readFileSync("package.json")).version)'
)
local TAG="v${NEW_VERSION}"
local BRANCH="release/v${NEW_VERSION}"
local BASE_BRANCH="${TAG%%.*}"
local VERSION=$1
check_version_format ${VERSION}
check_version_format ${NEW_VERSION}
check_current_branch ${BASE_BRANCH}
update_changelog ${VERSION}
update_package_version ${VERSION}
update_dependencies_version
regenerate_package_lock
build_package
commit_changes ${VERSION}
create_branch ${BRANCH} ${BASE_BRANCH}
update_package_version ${NEW_VERSION}
update_changelog ${NEW_VERSION}
verify_package
commit_changes ${NEW_VERSION}
finish ${NEW_VERSION} ${CURRENT_VERSION} ${BRANCH} ${BASE_BRANCH} ${TAG}
}
function usage() {
local COMMAND=`basename ${0}`
local COMMAND=$(basename ${0})
echo -e "${COLOR_SECTION}NAME${COLOR_RESET}
${COMMAND} - Prepare for new release
@ -44,12 +62,13 @@ ${COLOR_SECTION}SYNOPSIS${COLOR_RESET}
${COLOR_COMMAND_NAME}${COMMAND}${COLOR_RESET} <${COLOR_OPTION}new-version${COLOR_RESET}>
${COLOR_SECTION}DESCRIPTION${COLOR_RESET}
This command:
- updates ${COLOR_FILE}CHANGELOG.md${COLOR_RESET}
- updates package version in ${COLOR_FILE}package.json${COLOR_RESET}
- updates dependencies version in ${COLOR_FILE}package.json${COLOR_RESET}
- verifies
- ...and commits!
This command will...
- create a new branch for release
- update ${COLOR_FILE}CHANGELOG.md${COLOR_RESET}
- update package version in ${COLOR_FILE}package.json${COLOR_RESET}
- update dependencies version in ${COLOR_FILE}package.json${COLOR_RESET}
- verify
- ...and commit!
${COLOR_OPTION}new-version${COLOR_RESET} must follow \"Semantic Versioning\" <https://semver.org/>.
"
@ -57,7 +76,7 @@ ${COLOR_SECTION}DESCRIPTION${COLOR_RESET}
}
function check_version_format() {
if [[ $1 =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then
if [[ ${1} =~ ^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*) ]]; then
return
fi
@ -66,47 +85,118 @@ function check_version_format() {
exit 2
}
function check_current_branch() {
local BASE_BRANCH=$1
local CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [ ${CURRENT_BRANCH} = ${BASE_BRANCH} ]; then
return
fi
echo -e "${COLOR_ERROR}ERROR:${COLOR_RESET} Work on ${COLOR_BRANCH}${BASE_BRANCH}${COLOR_RESET} branch
${COLOR_COMMAND}git checkout ${BASE_BRANCH}${COLOR_RESET}
" >&2
exit 2
}
function create_branch() {
local BRANCH=$1
local BASE_BRANCH=$2
git checkout -b ${BRANCH} ${BASE_BRANCH}
}
function update_package_version() {
local VERSION=$1
npm version --no-git-tag-version ${VERSION}
}
function update_changelog() {
local VERSION=$1
local DATE=`date "+%Y-%m-%d"`
local KEYWORD="Unreleased"
sed -i".bak" -r \
-e "s/^((##\s+)\[${KEYWORD}\])$/\1\n\n\2[${VERSION}] - ${DATE}/" \
-e "s/^((##[[:space:]]+)\[${KEYWORD}\])$/\1\n\n\2[${VERSION}] - ${DATE}/" \
-e "s/^(\[${KEYWORD}\](.*))(v.*)\.\.\.HEAD$/\1v${VERSION}...HEAD\n[${VERSION}]\2\3...v${VERSION}/" \
CHANGELOG.md
}
function update_package_version() {
local VERSION=$1
sed -i".bak" -r \
-e "s/(\"version\"\s*:\s*)\".*?\"/\1\"${VERSION}\"/" \
package.json
}
function update_dependencies_version() {
npm ci
npm run check-updates -- -u
}
function regenerate_package_lock() {
rm -rf package-lock.json node_modules
npm install
}
function build_package() {
npm run build
function verify_package() {
npm run verify
}
function commit_changes() {
local VERSION=$1
rm -rf node_modules
npm ci --only=production
git add CHANGELOG.md package.json package-lock.json node_modules lib
git add CHANGELOG.md package.json package-lock.json
git commit -m "version ${VERSION}"
}
function finish() {
local NEW_VERSION="${1}"
local CURRENT_VERSION="${2}"
local BRANCH="${3}"
local BASE_BRANCH="${4}"
local TAG="${5}"
local TITLE="${GITHUB_REPO} ${NEW_VERSION} released"
local CHANGELOG=$(
git diff v${CURRENT_VERSION} -- CHANGELOG.md |
sed -r -e '/^[^+]/d' -e 's/^\+(.*)$/\1/' -e '/^## /d' -e '/^\+/d' -e '/^\[/d' |
urlencode |
replace_lf
)
local PRERELEASE=0
if [[ ${NEW_VERSION} == "0."* ]]; then
# < 1.0.0
PRERELEASE=1
fi
if [[ ${NEW_VERSION} =~ -[0-9a-zA-Z] ]]; then
# -alpha, -pre, -rc, etc...
PRERELEASE=1
fi
echo -e "
Branch ${COLOR_BRANCH}${BRANCH}${COLOR_RESET} has been created.
Remaining processes are...
1. Make sure all changes are correct
${COLOR_COMMAND}git diff ${BASE_BRANCH} ${BRANCH}${COLOR_RESET}
2. Push to remote ${UPSTREAM}
${COLOR_COMMAND}git push --set-upstream ${UPSTREAM} ${BRANCH}${COLOR_RESET}
3. Create a pull-request: ${COLOR_BRANCH}${BRANCH}${COLOR_RESET} to ${COLOR_BRANCH}${BASE_BRANCH}${COLOR_RESET}
${URL_COMPARE}/${BASE_BRANCH}...${BRANCH}?expand=1
select ${COLOR_SELECT}Squash and merge${COLOR_RESET}
4. Create a new release
${URL_RELEASE}?tag=${TAG}&target=${BASE_BRANCH}&title=$(urlencode <<<"${TITLE}")&body=${CHANGELOG}&prerelease=${PRERELEASE}
Tag version: ${COLOR_INPUT}${TAG}${COLOR_RESET}
Target: ${COLOR_INPUT}${BASE_BRANCH}${COLOR_RESET}
Release title: ${COLOR_INPUT}${TITLE}${COLOR_RESET}
Description this release: (copy and paste CHANGELOG.md)
5. Post processing
${COLOR_COMMAND}git checkout ${BASE_BRANCH}${COLOR_RESET}
${COLOR_COMMAND}git pull${COLOR_RESET}
${COLOR_COMMAND}git fetch -p${COLOR_RESET}
${COLOR_COMMAND}git branch -D ${BRANCH}${COLOR_RESET}
That's all!
"
}
function urlencode() {
# https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding
sed -r \
-e 's/%/%25/g' \
-e 's/\$/%24/g' -e 's/\(/%28/g' -e 's/\)/%29/g' -e 's/\*/%2A/g' -e 's/\+/%2B/g' -e 's/\//%2F/g' -e 's/\?/%3F/g' -e 's/\[/%5B/g' -e 's/\]/%5D/g' \
-e 's/!/%21/g' -e 's/#/%23/g' -e 's/&/%26/g' -e "s/'/%27/g" -e 's/,/%2C/g' -e 's/:/%3A/g' -e 's/;/%3B/g' -e 's/=/%3D/g' -e 's/@/%40/g' \
-e 's/ /+/g'
}
function replace_lf() {
sed -r \
-e ':a' -e 'N' -e '$!ba' \
-e 's/^\n+//' -e 's/\n+$//' -e 's/\n/%0A/g'
}
main "$@"

View File

@ -1,6 +1,5 @@
#!/bin/bash
set -e
set -eu
npm ci
npm run build
@ -8,4 +7,4 @@ npm run verify
rm -rf node_modules
npm ci --only=production
git add node_modules lib
git add dist

View File

@ -1,16 +1,23 @@
#!/bin/bash
# update dependencies
set -e
set -eu
DATE=$(date +"%Y%m%d")
BRANCH=feature/update-dependencies-${DATE}
COLOR_SUCCESS="\e[1;32m"
COLOR_RESET="\e[m"
BASE_BRANCH=$(git rev-parse --abbrev-ref HEAD)
TARGET_BRANCH=feature/update-dependencies-${DATE}
# create branch
git checkout develop
git checkout -b ${BRANCH}
COLOR_SUCCESS="\033[1;32m"
COLOR_ERROR="\033[1;41m"
COLOR_RESET="\033[m"
cd $(dirname ${0})/..
# create target branch
if [[ ! ${BASE_BRANCH} =~ ^v[0-9]+$ ]]; then
echo -e "${COLOR_ERROR}Error:${COLOR_RESET} Base branch must match 'v*'; got '${BASE_BRANCH}'."
exit 1
fi
git checkout -b ${TARGET_BRANCH}
# check updates
npm ci
@ -19,22 +26,21 @@ npm run check-updates -- -u
# re-install packages
rm -rf package-lock.json node_modules
npm i
npm dedupe
# check
# test
npm run build
npm run verify
# commit
rm -rf node_modules
npm ci --only=production
git add package.json package-lock.json node_modules
git add package.json package-lock.json dist
git commit -m "update dependencies"
# finished!
echo -e "
${COLOR_SUCCESS}🎉All dependencies are updated successfully.🎉${COLOR_RESET}
Push changes and merge into 'develop' branch.
Push changes and merge into '${BASE_BRANCH}' branch.
git push --set-upstream origin ${BRANCH}
git push --set-upstream origin ${TARGET_BRANCH}
"

76
src/common.ts Normal file
View File

@ -0,0 +1,76 @@
import * as fs from "fs";
import * as os from "os";
import * as path from "path";
import * as core from "@actions/core";
/** state name of backup suffix */
const STATE_BACKUP_SUFFIX = "backup-suffix";
const STATE_CREATED_FILES = "created-files";
/**
* create backup suffix name
* @param dirName directory to back up
* @returns backup suffix; empty string if directory does not exist
*/
export function createBackupSuffix(dirName: string): string {
if (!fs.existsSync(dirName)) {
return "";
}
const backupSuffix = `.bak-${Date.now()}`;
core.saveState(STATE_BACKUP_SUFFIX, backupSuffix);
return backupSuffix;
}
/**
* get backup suffix name
* @returns backup suffix (if not, empty string)
*/
export function getBackupSuffix(): string {
return core.getState(STATE_BACKUP_SUFFIX);
}
/**
* save created file names
* @param fileNames array of file names
*/
export function saveCreatedFileNames(fileNames: string[]): void {
const json = JSON.stringify(fileNames);
core.saveState(STATE_CREATED_FILES, json);
}
/**
* save created file names
* @returns saved array of file names
*/
export function loadCreatedFileNames(): string[] {
const json = core.getState(STATE_CREATED_FILES);
if (json === "") {
return [];
}
return JSON.parse(json) as string[];
}
/**
* get SSH directory
* @returns SSH directory name
*/
export function getSshDirectory(): string {
return path.resolve(getHomeDirectory(), ".ssh");
}
/**
* get home directory
* @returns home directory name
*/
function getHomeDirectory(): string {
const homedir = os.homedir();
if (homedir === "/github/home") {
// Docker container
return "/root";
}
return homedir;
}

View File

@ -1,132 +1,223 @@
import fs from "fs";
import path from "path";
import * as fs from "fs";
import * as path from "path";
import * as core from "@actions/core";
interface FileInfo
{
name: string;
contents: string;
options: fs.WriteFileOptions;
import * as common from "./common";
/** file creation info */
interface FileInfo {
/** file name */
name: string;
/** file contents */
contents: string;
/** creation options */
options: fs.WriteFileOptions;
/** file must not exist when creating */
mustNotExist: boolean;
}
/** default known_hosts */
const KNOWN_HOSTS = [
"github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=",
];
try {
main();
} catch (err) {
if (err instanceof Error) {
core.setFailed(err);
}
}
/**
* main function
*/
function main(): void
{
try
{
const files: FileInfo[] = [
{
name: core.getInput("name"),
contents: core.getInput("key", {
required: true,
}),
options: {
mode: 0o400,
flag: "ax",
},
},
{
name: "known_hosts",
contents: insertLf(core.getInput("known_hosts", {
required: true,
})),
options: {
mode: 0o644,
flag: "a",
},
},
{
name: "config",
contents: insertLf(core.getInput("config")),
options: {
mode: 0o644,
flag: "a",
},
},
];
export function main(): void {
const sshDirName = common.getSshDirectory();
// create ".ssh" directory
const home = getHomeDirectory();
const dirName = path.resolve(home, ".ssh");
fs.mkdirSync(dirName, {
recursive: true,
mode: 0o700,
});
// create ".ssh" directory
const backupSuffix = common.createBackupSuffix(sshDirName);
if (backupSuffix === "") {
createDirectory(sshDirName);
console.log(`✅SSH directory "${sshDirName}" has been created successfully.`);
}
// create files
for(const file of files)
{
const fileName = path.join(dirName, file.name);
fs.writeFileSync(fileName, file.contents, file.options);
}
// files to be created
const files = buildFilesToCreate(sshDirName);
console.log(`SSH key has been stored to ${dirName} successfully.`);
}
catch(err)
{
core.setFailed(err.message);
}
// back up & create files
const createdFileNames: string[] = [];
const backedUpFileNames: string[] = [];
for (const file of files) {
const pathName = path.join(sshDirName, file.name);
if (backup(pathName, backupSuffix, file.mustNotExist)) {
backedUpFileNames.push(file.name);
}
fs.writeFileSync(pathName, file.contents, file.options);
createdFileNames.push(file.name);
}
common.saveCreatedFileNames(createdFileNames);
if (createdFileNames.length > 0) {
console.log(`✅Following files have been created in "${sshDirName}" successfully; ${createdFileNames.join(", ")}`);
}
if (backedUpFileNames.length > 0) {
console.log(`✅Following files have been backed up in suffix "${backupSuffix}" successfully; ${backedUpFileNames.join(", ")}`);
}
}
/**
* get home directory
* @returns home directory
* build files to create
* @param dirName directory name in where files will be created
* @returns files
*/
function getHomeDirectory(): string
{
const homeEnv = getHomeEnv();
const home = process.env[homeEnv];
if(home === undefined)
{
throw Error(`${homeEnv} is not defined`);
}
function buildFilesToCreate(dirName: string): FileInfo[] {
// parameters
const key = core.getInput("key", {
required: true,
});
const name = core.getInput("name");
const knownHosts = core.getInput("known_hosts", {
required: true,
});
const config = core.getInput("config");
const ifKeyExists = core.getInput("if_key_exists");
return home;
// files to be created
const files: FileInfo[] = [
{
name: "known_hosts",
contents: insertLf(buildKnownHostsArray(knownHosts).join("\n"), true, true),
options: {
mode: 0o644,
flag: "a",
},
mustNotExist: false,
},
];
if (shouldCreateKeyFile(path.join(dirName, name), ifKeyExists)) {
files.push({
name: name,
contents: insertLf(key, false, true),
options: {
mode: 0o400,
flag: "wx",
},
mustNotExist: true,
});
}
if (config !== "") {
files.push({
name: "config",
contents: insertLf(config, true, true),
options: {
mode: 0o644,
flag: "a",
},
mustNotExist: false,
});
}
return files;
}
/**
* get HOME environment name
* @returns HOME environment name
* create directory
* @param dirName directory name to remove
*/
function getHomeEnv(): string
{
if(process.platform === "win32")
{
// Windows
return "USERPROFILE";
}
function createDirectory(dirName: string): void {
fs.mkdirSync(dirName, {
recursive: true,
mode: 0o700,
});
}
// macOS / Linux
return "HOME";
/**
* back up file
* @param fileName file to back up
* @param backupSuffix suffix
* @param removeOrig remove original file
* @returns is file backed up?
*/
function backup(fileName: string, backupSuffix: string, removeOrig: boolean): boolean {
if (backupSuffix === "") {
return false;
}
if (!fs.existsSync(fileName)) {
return false;
}
// move -> copy (in order to keep permissions when restore)
const fileNameBak = `${fileName}${backupSuffix}`;
fs.renameSync(fileName, fileNameBak);
if (!removeOrig) {
fs.copyFileSync(fileNameBak, fileName);
}
return true;
}
/**
* prepend/append LF to value if not empty
* @param value the value to prepend LF
* @returns prepended value
* @param value the value to insert LF
* @param prepend true to prepend
* @param append true to append
* @returns new value
*/
function insertLf(value: string): string
{
let affectedValue = value;
function insertLf(value: string, prepend: boolean, append: boolean): string {
let affectedValue = value;
if(value.length === 0)
{
// do nothing if empty
return "";
}
if(!affectedValue.startsWith("\n"))
{
affectedValue = `\n${affectedValue}`;
}
if(!affectedValue.endsWith("\n"))
{
affectedValue = `${affectedValue}\n`;
}
if (value.length === 0) {
// do nothing if empty
return "";
}
if (prepend && !affectedValue.startsWith("\n")) {
affectedValue = `\n${affectedValue}`;
}
if (append && !affectedValue.endsWith("\n")) {
affectedValue = `${affectedValue}\n`;
}
return affectedValue;
return affectedValue;
}
main();
/**
* should create SSH key file?
* @param keyFilePath path of key file
* @param ifKeyExists action if SSH key exists
* @returns Yes/No
*/
function shouldCreateKeyFile(keyFilePath: string, ifKeyExists: string): boolean {
if (!fs.existsSync(keyFilePath)) {
// should create if file does not exist
return true;
}
switch (ifKeyExists) {
case "replace":
// should create if replace (existing file will be backed up when creating)
return true;
case "ignore":
// should NOT create if ignore
return false;
default:
// error otherwise
throw new Error(`SSH key is already installed. Set "if_key_exists" to "replace" or "ignore" in order to avoid this error.`);
}
}
/**
* build array of known_hosts
* @param knownHosts known_hosts
* @returns array of known_hosts
*/
function buildKnownHostsArray(knownHosts: string): string[] {
if (knownHosts === "unnecessary") {
return KNOWN_HOSTS;
}
return KNOWN_HOSTS.concat(knownHosts);
}

89
src/post.ts Normal file
View File

@ -0,0 +1,89 @@
import * as fs from "fs";
import * as path from "path";
import * as core from "@actions/core";
import * as common from "./common";
try {
post();
} catch (err) {
if (err instanceof Error) {
core.setFailed(err);
}
}
/**
* cleanup function
*/
export function post(): void {
const sshDirName = common.getSshDirectory();
const backupSuffix = common.getBackupSuffix();
if (backupSuffix === "") {
// remove ".ssh" directory if suffix is not set
removeDirectory(sshDirName);
console.log(`✅SSH directory "${sshDirName}" has been removed successfully.`);
} else {
// remove created files and restore from backup
const removedFileNames = removeCreatedFiles(sshDirName);
if (removedFileNames.length > 0) {
console.log(`✅Following files have been removed successfully; ${removedFileNames.join(", ")}`);
}
const restoredFileNames = restoreFiles(sshDirName, backupSuffix);
if (restoredFileNames.length > 0) {
console.log(`✅Following files in suffix "${backupSuffix}" have been restored successfully; ${restoredFileNames.join(", ")}`);
}
}
}
/**
* remove directory
* @param dirName directory name to remove
*/
function removeDirectory(dirName: string): void {
fs.rmSync(dirName, {
recursive: true,
force: true,
});
}
/**
* remove created files in main phase
* @param dirName directory name
* @returns removed file names
*/
function removeCreatedFiles(dirName: string): string[] {
const createdFileNames = common.loadCreatedFileNames();
for (const fileName of createdFileNames) {
const pathName = path.join(dirName, fileName);
fs.rmSync(pathName);
}
return createdFileNames;
}
/**
* restore files from backups
* @param dirName directory name
* @param backupSuffix suffix of backup directory
* @returns restored file names
*/
function restoreFiles(dirName: string, backupSuffix: string): string[] {
const restoredFileNames: string[] = [];
const entries = fs.readdirSync(dirName)
.filter((entry) => {
// skip if not a backed-up file
return entry.endsWith(backupSuffix);
});
for (const entry of entries) {
const entryOrg = entry.substring(0, entry.length - backupSuffix.length);
const pathNameOrg = path.join(dirName, entryOrg);
const pathNameBak = path.join(dirName, entry);
fs.renameSync(pathNameBak, pathNameOrg);
restoredFileNames.push(entryOrg);
}
return restoredFileNames;
}

View File

@ -2,11 +2,12 @@
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"moduleResolution": "node",
"lib": [
"es6"
],
"sourceMap": true,
"outDir": "./lib",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,