Skip to content

Commit

Permalink
Secrel Decouple (#2882)
Browse files Browse the repository at this point in the history
* first pass at changing secrel to be more decoupled

* work on syntax error

* put secrel inputs step in separate script

* change conditions

* checkout repo in secrel-inputs step

* add back double bracing

* add space in braces

* move script back

* add gate step

* change run conditions

* add debug echo statement

* change form of run condition

* change form of run condition

* change form of run condition

* change form of run condition

* change form of run condition

* change form of run condition

* change form of run condition

* change form of run condition

* change form of run condition

* change form of run condition

* change form of run condition

* change form of run condition

* change form of run condition

* change form of run condition

* change form of run condition

* change form of run condition

* change form of run condition

* update list

* update text

* update text

* try stop quote stripping

* try stop quote stripping

* try stop quote stripping
  • Loading branch information
msnwatson authored Apr 19, 2024
1 parent b4deccc commit 5b4794a
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 88 deletions.
190 changes: 102 additions & 88 deletions .github/workflows/secrel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
push:
branches: [ main, qa, develop, domain-* ]

# Run SecRel on Dependabot PRs, automatically
pull_request:
branches: [ develop ]

Expand All @@ -22,6 +23,37 @@ on:
required: true
type: boolean
default: true
publish_images:
description: "Publish all images from the head of the selected branch?"
required: true
type: boolean
default: false
image_name:
description: "Which images do you want to run SecRel on? This does not affect image publishing."
required: true
type: choice
default: all
options:
- all
- cc-app
- xample-workflows
- svc-bgs-api
- svc-bie-kafka
- svc-bip-api
- svc-lighthouse-api
- api-gateway
- ee-max-cfi-app
- ee-ep-merge-app
- dev-tools
- db-init
- app
- redis
- rabbitmq
image_tag:
description: "Image tag to run SecRel on. If 'all' is selected, then 'latest' will always be used. This does not define the image tag during publishing"
required: true
type: string
default: latest

env:
# Id for the #benefits-vro-devops Slack channel
Expand All @@ -33,33 +65,43 @@ jobs:
# only run for the internal repo, where the images are published
if: github.repository == 'department-of-veterans-affairs/abd-vro-internal'
outputs:
continue: ${{ steps.check-state.outputs.continue }}
run-secrel: ${{ steps.check-run-conds.outputs.run_secrel }}
publish-images: ${{ steps.check-run-conds.outputs.publish_images }}
runs-on: ubuntu-latest
steps:
- name: "Check trigger event"
id: check-state
- name: "Decide downstream actions"
id: check-run-conds
run: |
# Gate Check
if [ "${{ github.event_name }}" == "pull_request" ]; then
if echo "$GITHUB_HEAD_REF" | grep '^dependabot/'; then
CONTINUE=true
RUN_SECREL=true
PUBLISH_IMAGES=true
echo "Running SecRel against a Dependabot PR" | tee -a "$GITHUB_STEP_SUMMARY"
else
CONTINUE=false
RUN_SECREL=false
echo "For PRs, SecRel runs against only Dependabot PR" | tee -a "$GITHUB_STEP_SUMMARY"
fi
elif [ "${{ github.event_name }}" == "push" ]; then
PUBLISH_IMAGES=true
elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
RUN_SECREL=${{ inputs.run_secrel }}
PUBLISH_IMAGES=${{ inputs.publish_images }}
fi
echo "continue=${CONTINUE:-true}" >> "$GITHUB_OUTPUT"
{
echo "run_secrel=${RUN_SECREL:-true}"
echo "publish_images=${PUBLISH_IMAGES:-false}"
} >> "$GITHUB_OUTPUT"
# This step is always expected to output a non-empty list of images published
publish-to-ghcr:
name: Publish to GHCR
needs: gate-check
if: needs.gate-check.outputs.continue == 'true'
if: needs.gate-check.outputs.publish-images == 'true'
outputs:
vro-images: ${{ steps.publish-images.outputs.images_list }}
slack-response-ts: ${{ fromJson(steps.notify-slack.outputs.slack-result).response.message.ts }}
run-secrel: ${{ steps.image-props.outputs.run_secrel }}
runs-on: ubuntu-latest
steps:
- name: "Determine image tag"
Expand All @@ -68,21 +110,18 @@ jobs:
# Set defaults
IMG_TAG=${GITHUB_SHA:0:7}
RUN_GRADLE_TESTS="true"
RUN_SECREL="true"
# Override some defaults depending on the branch/ref_name
echo "ref_name: ${{ github.ref_name }}"
# If workflow was manually dispatched, override settings
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
RUN_GRADLE_TESTS=${{ inputs.run_tests }}
RUN_SECREL=${{ inputs.run_secrel }}
fi
{
echo "image_tag=${IMG_TAG}"
echo "run_tests=${RUN_GRADLE_TESTS}"
echo "run_secrel=${RUN_SECREL}"
} >> "$GITHUB_OUTPUT"
- name: "DEBUG"
Expand Down Expand Up @@ -127,89 +166,64 @@ jobs:
slack-optional-thread_ts: ${{ fromJson(steps.notify-slack.outputs.slack-result).response.message.ts }}
slack-text: ":panda_builder: Images published!"

debug-job:
needs: publish-to-ghcr
secrel-inputs:
if: ${{ !failure() }}
needs: [publish-to-ghcr, gate-check]
outputs:
vro-images: ${{ steps.vro-images.outputs.image_list }}
runs-on: ubuntu-latest
steps:
- name: show vars
- name: "Checkout source code"
uses: actions/checkout@v4
with:
# Checkout using a PAT so that we can do `git push` later in publish-images
token: ${{ secrets.ACCESS_TOKEN_PUSH_TO_DEVELOP }}
- name: "Determine VRO image inputs"
id: vro-images
env:
IMAGE_ARR: ${{needs.publish-to-ghcr.outputs.vro-images}}
run: |
echo "ref_name: ${{github.ref_name}}"
echo "vro-images: ${{ needs.publish-to-ghcr.outputs.vro-images }}"
source scripts/image_vars.src
IMAGE_LIST="[]"
secrel:
name: SecRel Pipeline
needs: publish-to-ghcr
if: needs.publish-to-ghcr.outputs.run-secrel == 'true'
uses: department-of-veterans-affairs/lighthouse-tornado-secrel-pipeline/.github/workflows/pipeline.yml@v5
with:
config-file: .github/secrel/config.yml
images: ${{ needs.publish-to-ghcr.outputs.vro-images }}
secrets: inherit
# This case captures manual dispatches where publishing is disabled
if [ "${{ needs.publish-to-ghcr.result }}" == 'skipped' ]; then
notify-secrel-error:
needs: secrel
if: always() && needs.secrel.result == 'failure'
runs-on: ubuntu-latest
steps:
- name: "Slack: SecRel Failure"
uses: archive/[email protected]
# only run for the internal repo
if: ${{ github.repository == 'department-of-veterans-affairs/abd-vro-internal' }}
with:
slack-bot-user-oauth-access-token: ${{ secrets.SLACK_BOT_USER_OAUTH_ACCESS_TOKEN }}
slack-channel: ${{ env.SLACK_CHANNEL }}
slack-text: ":redlight: <${{github.server_url}}/${{github.repository}}/actions/runs/${{github.run_id}}|\
SecRel scan (#${{ github.run_number }}) failed>! \n\
${{github.ref_type}} `${{github.ref_name}}` (`${{github.sha}}`), \n\
caused by `${{github.event_name}}` triggered by `${{github.triggering_actor}}` ..."
IMAGE_LIST="["
slack-final:
needs: [ gate-check, publish-to-ghcr, secrel]
runs-on: ubuntu-latest
if: always()
steps:
- name: "Set status message"
run: |
URL=${{github.server_url}}/${{github.repository}}/actions/runs/${{github.run_id}}
{
if [ "${{needs.publish-to-ghcr.result}}" == 'failure' ]; then
echo "WORKFLOW_STATE_TEXT=:panda_blank: <$URL|Publishing> failed!"
echo 'WORKFLOW_STATE_EMOJI=x'
elif [ "${{needs.secrel.result}}" == 'failure' ]; then
echo "WORKFLOW_STATE_TEXT=:panda_cop: <$URL|SecRel> failed!"
echo 'WORKFLOW_STATE_EMOJI=x'
elif [ "${{needs.secrel.result}}" == 'success' ]; then
echo "WORKFLOW_STATE_TEXT=:panda-yay: SecRel passed and images signed!"
echo 'WORKFLOW_STATE_EMOJI=panda-yay'
elif [ "${{needs.publish-to-ghcr.result}}" == 'skipped' ]; then
echo "WORKFLOW_STATE_TEXT=:black_square_for_stop: <$URL|Publishing> skipped"
echo 'WORKFLOW_STATE_EMOJI=black_square_for_stop'
elif [ "${{needs.publish-to-ghcr.outputs.run-secrel}}" == "true" ] && [ "${{needs.secrel.result}}" != 'success' ]; then
echo "WORKFLOW_STATE_TEXT=:black_square_for_stop: <$URL|SecRel> ${{needs.secrel.result}}"
echo 'WORKFLOW_STATE_EMOJI=black_square_for_stop'
elif [ "${{needs.publish-to-ghcr.outputs.run-secrel}}" == "false" ] && [ "${{needs.publish-to-ghcr.result}}" == 'success' ]; then
echo "WORKFLOW_STATE_TEXT=:heavy_check_mark: Run completed (without SecRel scans or signing images)"
echo 'WORKFLOW_STATE_EMOJI=heavy_check_mark'
if [ "${{inputs.image_name}}" == 'all' ]; then
for PREFIX in "${VAR_PREFIXES_ARR[@]}"; do
IMG_NAME="$(getVarValue "${PREFIX}" _IMG)"
GHCR_PATH="ghcr.io/${{github.repository}}/${IMG_NAME}"
IMAGE_LIST+="\"${GHCR_PATH}:latest\","
done
# Remove the trailing comma
IMAGE_LIST=${IMAGE_LIST%?}
else
echo "WORKFLOW_STATE_TEXT=publish: ${{needs.publish-to-ghcr.result}}; secrel: ${{needs.secrel.result}}"
echo 'WORKFLOW_STATE_EMOJI=shrug'
IMG_TAG="${{inputs.image_tag}}"
IMG_NAME="$(getVarValue "$(bashVarPrefix "${{inputs.image_name}}")" _IMG)"
GHCR_PATH="ghcr.io/${{github.repository}}/${IMG_NAME}"
IMAGE_LIST+="\"${GHCR_PATH}:${IMG_TAG}\""
fi
} >> "$GITHUB_ENV"
- name: "Slack thread: Post final status"
if: always() && needs.gate-check.outputs.continue == 'true'
uses: archive/[email protected]
with:
slack-bot-user-oauth-access-token: ${{ secrets.SLACK_BOT_USER_OAUTH_ACCESS_TOKEN }}
slack-channel: ${{ env.SLACK_CHANNEL }}
slack-optional-thread_ts: ${{ needs.publish-to-ghcr.outputs.slack-response-ts }}
slack-text: ${{ env.WORKFLOW_STATE_TEXT }}
- name: "Slack emoji: React success on top-level Slack notification"
if: always() && needs.gate-check.outputs.continue == 'true'
uses: archive/[email protected]
with:
slack-function: send-reaction
slack-bot-user-oauth-access-token: ${{ secrets.SLACK_BOT_USER_OAUTH_ACCESS_TOKEN }}
slack-channel: ${{ env.SLACK_CHANNEL }}
slack-message-timestamp: ${{ needs.publish-to-ghcr.outputs.slack-response-ts }}
slack-emoji-name: ${{ env.WORKFLOW_STATE_EMOJI }}
IMAGE_LIST+="]"
echo "image_list=${IMAGE_LIST}" >> "$GITHUB_OUTPUT"
# This case captures when the workflow is run automatically on PR merge along
# with manual dispatches where publishing is enabled
elif [ "${{needs.publish-to-ghcr.result}}" == 'success' ]; then
echo "image_list=$IMAGE_ARR" >> "$GITHUB_OUTPUT"
fi
secrel:
name: SecRel Pipeline
needs: [secrel-inputs, gate-check]
if: ${{always() && needs.gate-check.outputs.run-secrel == 'true'}}
secrets: inherit
uses: department-of-veterans-affairs/lighthouse-tornado-secrel-pipeline/.github/workflows/pipeline.yml@v5
with:
config-file: .github/secrel/config.yml
images: ${{ needs.secrel-inputs.outputs.vro-images }}
42 changes: 42 additions & 0 deletions scripts/secrel-secrel-inputs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env bash

# This script is only used as the secrel-inputs step in the Secrel GH workflow

source scripts/image_vars.src
IMAGE_LIST="[]"

# This case captures manual dispatches where publishing is disabled
if [ "${{ needs.publish-to-ghcr.result }}" == 'skipped' ]; then

IMAGE_LIST="["

if [ "${{inputs.image_name}}" == 'all' ]; then
for PREFIX in "${VAR_PREFIXES_ARR[@]}"; do
IMG_NAME="$(getVarValue "${PREFIX}" _IMG)"
GHCR_PATH="ghcr.io/${{github.repository}}/${IMG_NAME}"
IMAGE_LIST+="\"${GHCR_PATH}:latest\","
done

# Remove the trailing comma
IMAGE_LIST=${IMAGE_LIST%?}
else
IMG_TAG="${{inputs.image_tag}}"
IMG_NAME="$(getVarValue "$(bashVarPrefix "${{inputs.image_name}}")" _IMG)"
GHCR_PATH="ghcr.io/${{github.repository}}/${IMG_NAME}"
IMAGE_LIST+="\"${GHCR_PATH}:${IMG_TAG}\""
fi

IMAGE_LIST+="]"

# This case captures when the workflow is run automatically on PR merge along
# with manual dispatches where publishing is disabled
elif [ "${{needs.publish-to-ghcr.result}}" == 'success' ]; then
IMAGE_LIST=${{needs.publish-to-ghcr.outputs.vro-images}}
fi

# Throw an error if the IMAGE_LIST variable is an empty array
if [ "${IMAGE_LIST}" == "[]" ]; then
exit 1
fi

echo "image_list=${IMAGE_LIST}" >> "$GITHUB_OUTPUT"

0 comments on commit 5b4794a

Please sign in to comment.