From 4551b03120915c2a909510e705a16be52faec45b Mon Sep 17 00:00:00 2001 From: Ruud Senden <8635138+rsenden@users.noreply.github.com> Date: Fri, 31 May 2024 11:01:08 +0200 Subject: [PATCH] chore: Refactor login/logout actions --- internal/fod-login/action.yml | 30 ++++-------- internal/fod-login/login.sh | 18 ++++++++ internal/fod-login/logout.sh | 5 ++ internal/fod-logout/action.yml | 14 ------ internal/run-script/action.yml | 20 ++++++++ internal/run-script/main.js | 21 +++++++++ .../package-lock.json | 0 internal/sc-sast-login/action.yml | 44 ++++++++++-------- internal/sc-sast-logout/action.yml | 16 ------- internal/with-post-step/action.yml | 42 ----------------- internal/with-post-step/main.js | 46 ------------------- 11 files changed, 97 insertions(+), 159 deletions(-) create mode 100755 internal/fod-login/login.sh create mode 100755 internal/fod-login/logout.sh delete mode 100644 internal/fod-logout/action.yml create mode 100644 internal/run-script/action.yml create mode 100644 internal/run-script/main.js rename internal/{with-post-step => run-script}/package-lock.json (100%) delete mode 100644 internal/sc-sast-logout/action.yml delete mode 100644 internal/with-post-step/action.yml delete mode 100644 internal/with-post-step/main.js diff --git a/internal/fod-login/action.yml b/internal/fod-login/action.yml index 6a6a230..f2fe85a 100644 --- a/internal/fod-login/action.yml +++ b/internal/fod-login/action.yml @@ -1,30 +1,18 @@ name: 'Run "fcli fod session login" command' -description: 'Run "fcli fod session login" command based on environment variables' +description: 'Run "fcli fod session login" command based on environment variables, auto-logout on job termination' author: 'Fortify' runs: using: composite steps: - # Define login options - - run: | - if [ -z "$FOD_URL" ]; then - echo "ERROR: FOD_URL environment variable must be set"; exit 1; - fi - if [ -n "${FOD_CLIENT_ID}" -a -n "${FOD_CLIENT_SECRET}" ]; then - echo '_FOD_LOGIN_OPTS=--url "${FOD_URL}" --client-id "${FOD_CLIENT_ID}" --client-secret "${FOD_CLIENT_SECRET}" ${EXTRA_FOD_LOGIN_OPTS}' >> $GITHUB_ENV - elif [ -n "${FOD_USER}" -a -n "${FOD_PASSWORD}" -a -n "${FOD_TENANT}" ]; then - echo '_FOD_LOGIN_OPTS=--url "${FOD_URL}" -t "${FOD_TENANT}" -u "${FOD_USER}" -p "${FOD_PASSWORD}" ${EXTRA_FOD_LOGIN_OPTS}' >> $GITHUB_ENV - else - echo "ERROR: Either FOD_CLIENT_ID and FOD_CLIENT_SECRET, or FOD_TENANT, FOD_USER and FOD_PASSWORD environment variables must be set"; exit 1; - fi - shell: bash - # Run fcli login command; note that the calling action/workflow is responsible for installing fcli - - uses: fortify/github-action/internal/run@feat-1.3.0 + # If not run before: check preconditions, run fcli login command, and run + # post-job fcli logout command. + # Note that the calling action/workflow is responsible for installing fcli + - uses: fortify/github-action/internal/run-script@feat-1.3.0 + if: ${{ !env._FOD_LOGGED_IN }} with: - cmd: '"${FCLI_CMD}" fod session login ${_FOD_LOGIN_OPTS}' - # Clean up temporary environment variables - - run: | - echo '_FOD_LOGIN_OPTS=""' >> $GITHUB_ENV - shell: bash + script: ${{ github.action_path }}/login.sh + post: ${{ github.action_path }}/logout.sh + branding: icon: 'shield' color: 'blue' diff --git a/internal/fod-login/login.sh b/internal/fod-login/login.sh new file mode 100755 index 0000000..d9be3af --- /dev/null +++ b/internal/fod-login/login.sh @@ -0,0 +1,18 @@ +#!/bin/bash +if [ -z "$FCLI_CMD" ]; then + echo "ERROR: fortify/github-action/setup must be run to set up fcli before running this action" + exit 1; +fi +if [ -z "$FOD_URL" ]; then + echo "ERROR: FOD_URL environment variable must be set"; exit 1; +fi +if [ -n "${FOD_CLIENT_ID}" -a -n "${FOD_CLIENT_SECRET}" ]; then + _FOD_AUTH_OPTS=("--client-id" "${FOD_CLIENT_ID} "--client-secret" "${FOD_CLIENT_SECRET}") +elif [ -n "${FOD_USER}" -a -n "${FOD_PASSWORD}" -a -n "${FOD_TENANT}" ]; then + _FOD_AUTH_OPTS=("-t" "${FOD_TENANT}" "-u" "${FOD_USER}" -p "${FOD_PASSWORD}") +else + echo "ERROR: Either FOD_CLIENT_ID and FOD_CLIENT_SECRET, or FOD_TENANT, FOD_USER and FOD_PASSWORD environment variables must be set" + exit 1; +fi +${FCLI_CMD} fod session login --url "${FOD_URL}" "${_FOD_AUTH_OPTS[@]}" ${EXTRA_FOD_LOGIN_OPTS} || exit 1 +echo '_FOD_LOGGED_IN=true' >> $GITHUB_ENV \ No newline at end of file diff --git a/internal/fod-login/logout.sh b/internal/fod-login/logout.sh new file mode 100755 index 0000000..c065d66 --- /dev/null +++ b/internal/fod-login/logout.sh @@ -0,0 +1,5 @@ +#!/bin/bash +if [[ "${_FOD_LOGGED_IN}" == "true" ]]; then + echo '_FOD_LOGGED_IN=false' >> $GITHUB_ENV + ${FCLI_CMD} fod session logout || exit 1 +fi \ No newline at end of file diff --git a/internal/fod-logout/action.yml b/internal/fod-logout/action.yml deleted file mode 100644 index ebe4eb6..0000000 --- a/internal/fod-logout/action.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: 'Run "fcli fod session login" command' -description: 'Run "fcli fod session login" command based on environment variables' -author: 'Fortify' -runs: - using: composite - steps: - # Run fcli logout command; note that the calling action/workflow is responsible for installing fcli - - uses: fortify/github-action/internal/run@feat-1.3.0 - with: - cmd: '"${FCLI_CMD}" fod session logout' -branding: - icon: 'shield' - color: 'blue' - diff --git a/internal/run-script/action.yml b/internal/run-script/action.yml new file mode 100644 index 0000000..1c45ec2 --- /dev/null +++ b/internal/run-script/action.yml @@ -0,0 +1,20 @@ +name: Run a script with optional post-job cleanup + +description: 'Action to execute a bash script, optionally executing another script on job completion.' + +inputs: + script: + description: 'Script to run' + required: true + post: + description: 'Script to run on job completion' + required: false + key: + description: 'Name of the state variable used to detect the post step.' + required: false + default: POST + +runs: + using: 'node20' + main: 'main.js' + post: 'main.js' diff --git a/internal/run-script/main.js b/internal/run-script/main.js new file mode 100644 index 0000000..0ee2324 --- /dev/null +++ b/internal/run-script/main.js @@ -0,0 +1,21 @@ +const { spawn } = require("child_process"); +const { appendFileSync } = require("fs"); +const { EOL } = require("os"); + +function run(script) { + if ( script ) { + const subprocess = spawn(`bash -c -o pipefail -v ${script}`, { stdio: "inherit", shell: true }); + subprocess.on("exit", (exitCode) => { + process.exitCode = exitCode; + }); + } +} + +const key = process.env.INPUT_KEY.toUpperCase(); + +if ( process.env[`STATE_${key}`] !== undefined ) { // Are we in the 'post' step? + run(process.env.INPUT_POST); +} else { // Otherwise, this is the main step + appendFileSync(process.env.GITHUB_STATE, `${key}=true${EOL}`); + run(process.env.INPUT_SCRIPT); +} diff --git a/internal/with-post-step/package-lock.json b/internal/run-script/package-lock.json similarity index 100% rename from internal/with-post-step/package-lock.json rename to internal/run-script/package-lock.json diff --git a/internal/sc-sast-login/action.yml b/internal/sc-sast-login/action.yml index 703c013..21ffc9b 100644 --- a/internal/sc-sast-login/action.yml +++ b/internal/sc-sast-login/action.yml @@ -7,27 +7,31 @@ runs: # TODO If we wait for scan completion, potentially we could generate a CIToken if # SSC_USER and SSC_PASSWORD have been set, and then revoke the token once the # scan has been successfully processed on SSC. - # Define login options - - run: | - if [ -z "$SSC_URL" ]; then - echo "ERROR: SSC_URL environment variable must be set"; exit 1; - fi - if [ -z "$SC_SAST_TOKEN" ]; then - echo "ERROR: SC_SAST_TOKEN environment variable must be set"; exit 1; - fi - if [ -z "SSC_TOKEN" ]; then - echo "ERROR: SSC_TOKEN environment variable must be set"; exit 1; - fi - echo '_SC_SAST_LOGIN_OPTS=--ssc-url "${SSC_URL}" -t "${SSC_TOKEN}" -c "${SC_SAST_TOKEN}" ${EXTRA_SC_SAST_LOGIN_OPTS}' >> $GITHUB_ENV - shell: bash - # Run fcli login command; note that the calling action/workflow is responsible for installing fcli - - uses: fortify/github-action/internal/run@feat-1.3.0 + + # If not run before: check preconditions, run fcli login command, and run + # post-job fcli logout command. + # Note that the calling action/workflow is responsible for installing fcli + - uses: fortify/github-action/internal/with-post-step@feat-1.3.0 + if: ${{ !env._SC_SAST_LOGGED_IN } with: - cmd: '"${FCLI_CMD}" sc-sast session login ${_SC_SAST_LOGIN_OPTS}' - # Clean up temporary environment variables - - run: | - echo '_SC_SAST_LOGIN_OPTS=""' >> $GITHUB_ENV - shell: bash + main: | + if [ -z "$SSC_URL" ]; then + echo "ERROR: SSC_URL environment variable must be set"; exit 1; + fi + if [ -z "$SC_SAST_TOKEN" ]; then + echo "ERROR: SC_SAST_TOKEN environment variable must be set"; exit 1; + fi + if [ -z "SSC_TOKEN" ]; then + echo "ERROR: SSC_TOKEN environment variable must be set"; exit 1; + fi + "${FCLI_CMD}" sc-sast session login --ssc-url "${SSC_URL}" -t "${SSC_TOKEN}" -c "${SC_SAST_TOKEN}" ${EXTRA_SC_SAST_LOGIN_OPTS} + echo '_SC_SAST_LOGGED_IN=true' >> $GITHUB_ENV + post: | + if [[] "${_SC_SAST_LOGGED_IN}" == "true" ]; then + echo '_SC_SAST_LOGGED_IN=false' >> $GITHUB_ENV + "${FCLI_CMD}" sc-sast session logout --no-revoke-token + fi + branding: icon: 'shield' color: 'blue' diff --git a/internal/sc-sast-logout/action.yml b/internal/sc-sast-logout/action.yml deleted file mode 100644 index c4e7cf9..0000000 --- a/internal/sc-sast-logout/action.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: 'Run "fcli fod session login" command' -description: 'Run "fcli fod session login" command based on environment variables' -author: 'Fortify' -runs: - using: composite - steps: - # Run fcli logout command; note that the calling action/workflow is responsible for installing fcli - - uses: fortify/github-action/internal/run@feat-1.3.0 - with: - # TODO If we add functionality for generating a CIToken in the sc-sast-login - # action, we should clean it up here. - cmd: '"${FCLI_CMD}" sc-sast session logout --no-revoke-token' -branding: - icon: 'shield' - color: 'blue' - diff --git a/internal/with-post-step/action.yml b/internal/with-post-step/action.yml deleted file mode 100644 index 69c2a6e..0000000 --- a/internal/with-post-step/action.yml +++ /dev/null @@ -1,42 +0,0 @@ -# ==================================================================================================================== # -# Authors: # -# Patrick Lehmann # -# Unai Martinez-Corral # -# # -# ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); # -# you may not use this file except in compliance with the License. # -# You may obtain a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -# # -# SPDX-License-Identifier: Apache-2.0 # -# ==================================================================================================================== # -name: With post step - -description: 'Generic JS Action to execute a main command and set a command as a post step.' - -inputs: - main: - description: 'Main command/script.' - required: true - post: - description: 'Post command/script.' - required: true - key: - description: 'Name of the state variable used to detect the post step.' - required: false - default: POST - -runs: - using: 'node20' - main: 'main.js' - post: 'main.js' diff --git a/internal/with-post-step/main.js b/internal/with-post-step/main.js deleted file mode 100644 index 04c2a9d..0000000 --- a/internal/with-post-step/main.js +++ /dev/null @@ -1,46 +0,0 @@ -/* ================================================================================================================== * - * Authors: * - * Unai Martinez-Corral * - * * - * ================================================================================================================== * - * Copyright 2021-2022 Unai Martinez-Corral * - * Copyright 2022 Unai Martinez-Corral * - * * - * Licensed under the Apache License, Version 2.0 (the "License"); * - * you may not use this file except in compliance with the License. * - * You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, software * - * distributed under the License is distributed on an "AS IS" BASIS, * - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * - * See the License for the specific language governing permissions and * - * limitations under the License. * - * * - * SPDX-License-Identifier: Apache-2.0 * - * ================================================================================================================== * - * * - * Context: * - * * https://github.com/docker/login-action/issues/72 * - * * https://github.com/actions/runner/issues/1478 * - * ================================================================================================================== */ -const { spawn } = require("child_process"); -const { appendFileSync } = require("fs"); -const { EOL } = require("os"); - -function run(cmd) { - const subprocess = spawn(cmd, { stdio: "inherit", shell: true }); - subprocess.on("exit", (exitCode) => { - process.exitCode = exitCode; - }); -} - -const key = process.env.INPUT_KEY.toUpperCase(); - -if ( process.env[`STATE_${key}`] !== undefined ) { // Are we in the 'post' step? - run(process.env.INPUT_POST); -} else { // Otherwise, this is the main step - appendFileSync(process.env.GITHUB_STATE, `${key}=true${EOL}`); - run(process.env.INPUT_MAIN); -}