Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move swat tests from terra-github-workflows into rawls #2991

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
330 changes: 330 additions & 0 deletions .github/workflows/rawls-swat-tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,330 @@
name: rawls-swat-tests
run-name: ${{ inputs.run-name }}
on:
workflow_dispatch:
inputs:
additional-args:
description: JSON of additional options
type: string
default: "{'logging':'true','java-version':'17','billing-project':''}"
required: false
run-name:
description: 'Specify the run name to fetch workflow run ID based on run-name'
required: false
type: string
bee-name:
description: 'hostname of the BEE to run tests against'
required: true
type: string
ENV:
description: 'test environment'
required: true
type: choice
options:
- dev
- alpha
- staging
- qa
ref:
description: 'the branch, tag or SHA to checkout'
required: false
type: string
test-group-name:
description: 'Rawls test group name'
required: false
type: string
default: ''
test-context:
description: "Name of the texting context"
required: true
type: choice
default: "pr-test"
options:
- pr-test
- dev-merge
- manual
test-command:
description: 'sbt test command'
required: true
type: string
e2e-env:
description: 'The name of a .env file that contains envvars for E2E tests.'
required: false
default: ''
user-subjects:
description: 'An e2e test users map in JSON format. This map includes pre-seeded users in BEE, and it also contains the definition of the service account used for impersonation within the user-subjects.'
required: false
default: '{"service_account":"[email protected]","owners":["[email protected]"],"students":["[email protected]"]}'
type: string

env:
SERVICE_REPO: rawls
test_run_id: ${{ github.run_id }}

jobs:
# We use a plural form here to indicate we may modify this job to support multiple owners in the future.
obtain-owner-tokens:
strategy:
matrix:
owner_subject: ${{ fromJson(inputs['user-subjects']).owners }}
svc_account: [ "${{ fromJson(inputs['user-subjects']).service_account }}" ]

runs-on: ubuntu-latest
permissions:
contents: 'read'
id-token: 'write'

steps:
- uses: actions/checkout@v4

- name: 'Obtain OAuth2 2.0 Access Token'
id: 'obtain-owner-token'
uses: google-github-actions/auth@v2
with:
token_format: 'access_token'
workload_identity_provider: 'projects/1038484894585/locations/global/workloadIdentityPools/github-wi-pool/providers/github-wi-provider'
service_account: ${{ matrix.svc_account }}
access_token_scopes: 'profile, email, openid'
access_token_subject: ${{ matrix.owner_subject }}
export_environment_variables: false

- name: 'Set up owner metadata: email, type, and auth token as a JSON string'
id: 'setup-owner-metadata'
run: |
echo "::add-mask::${{ steps.obtain-owner-token.outputs.access_token }}"
echo "{\"email\":\"${{ matrix.owner_subject }}\",\"type\":\"owner\",\"bearer\":\"${{ steps.obtain-owner-token.outputs.access_token }}\"}" > "${{ matrix.owner_subject }}.json"

- name: 'Cache owner metadata to share with other jobs'
id: 'cache-owner-metadata'
uses: actions/upload-artifact@v3
with:
name: users-metadata-cache-${{ inputs.run-name }}
path: |
${{ matrix.owner_subject }}.json
retention-days: 1

# This job obtains access tokens for the rest of the user subjects that do not belong to owner type
obtain-tokens:
strategy:
matrix:
user_subject: ${{ fromJson(inputs['user-subjects']).students }}
svc_account: [ "${{ fromJson(inputs['user-subjects']).service_account }}" ]

runs-on: ubuntu-latest
permissions:
contents: 'read'
id-token: 'write'

steps:
- uses: actions/checkout@v4

- name: 'Obtain OAuth2 2.0 Access Token'
id: 'obtain-token'
uses: google-github-actions/auth@v2
with:
token_format: 'access_token'
workload_identity_provider: 'projects/1038484894585/locations/global/workloadIdentityPools/github-wi-pool/providers/github-wi-provider'
service_account: ${{ matrix.svc_account }}
access_token_scopes: 'profile, email, openid'
access_token_subject: ${{ matrix.user_subject }}
export_environment_variables: false

- name: 'Set up user metadata: email, type, and auth token as a JSON string'
id: 'setup-user-metadata'
run: |
echo "::add-mask::${{ steps.obtain-token.outputs.access_token }}"
echo "{\"email\":\"${{ matrix.user_subject }}\",\"type\":\"student\",\"bearer\":\"${{ steps.obtain-token.outputs.access_token }}\"}" > "${{ matrix.user_subject }}.json"

- name: 'Cache user metadata to share with other jobs'
id: 'cache-user-metadata'
uses: actions/upload-artifact@v3
with:
name: users-metadata-cache-${{ inputs.run-name }}
path: |
${{ matrix.user_subject }}.json
retention-days: 1

# Serialize all users metadata into B64-encoded JSON string
serialize-users-metadata:
runs-on: ubuntu-latest
needs: [obtain-owner-tokens, obtain-tokens]

steps:
- name: 'Pull users metadata from users-metadata-cache'
uses: actions/download-artifact@v3
with:
name: users-metadata-cache-${{ inputs.run-name }}

- name: 'Concatenate users metadata as a JSON string'
id: 'concatenate-users-metadata'
run: |
users_metadata_json=""
owners=$(echo '${{ inputs['user-subjects'] }}' | jq -r '.owners[]')
if [ -n "$owners" ]; then
for owner in $owners; do
owner_metadata=$(cat "${owner}.json")
if [ -n "$users_metadata_json" ]; then
users_metadata_json="${users_metadata_json},"
fi
users_metadata_json="${users_metadata_json}${owner_metadata}"
done
fi
subjects=$(echo '${{ inputs['user-subjects'] }}' | jq -r '.students[]')
if [ -n "$subjects" ]; then
for subject in $subjects; do
subject_metadata=$(cat "${subject}.json")
if [ -n "$users_metadata_json" ]; then
users_metadata_json="${users_metadata_json},"
fi
users_metadata_json="${users_metadata_json}${subject_metadata}"
done
fi
users_metadata_json="[${users_metadata_json}]"
users_metadata_json_b64=$(printf '%s' $users_metadata_json | base64 -w0)
echo "$users_metadata_json_b64" > users_metadata_json.b64

- name: 'Cache Users Metadata JSON (B64-encoded). This step is required in order to use add-mask to prevent leakage of secrets in subsequent jobs.'
id: 'cache-users-metadata-b64'
uses: actions/upload-artifact@v3
with:
name: users-metadata-cache-${{ inputs.run-name }}
path: |
users_metadata_json.b64
retention-days: 1

# This job will run Rawls swat tests against BEE_NAME.
rawls-swat-test-job:
runs-on: ubuntu-latest
needs: [serialize-users-metadata]
permissions:
contents: 'read'
id-token: 'write'
checks: 'write'

steps:
- uses: 'actions/checkout@v4'

- name: 'Pull users metadata from users-metadata-cache'
uses: actions/download-artifact@v3
with:
name: users-metadata-cache-${{ inputs.run-name }}

- name: Import Vault Secrets
uses: hashicorp/vault-action@v3
with:
url: https://clotho.broadinstitute.org:8200
method: approle
roleId: ${{ secrets.VAULT_ROLE_ID }}
secretId: ${{ secrets.VAULT_SECRET_ID }}
tlsSkipVerify: true
exportToken: true
secrets: |
secret/dsde/firecloud/${{ inputs.ENV }}/common/secrets firecloud_id | FIRECLOUD_ID;
secret/dsde/firecloud/${{ inputs.ENV }}/common/users automation_users_passwd | AUTOMATION_USERS_PASSWD;
secret/dsde/firecloud/${{ inputs.ENV }}/common/users billing_acct | BILLING_ACCT;
secret/dsde/firecloud/${{ inputs.ENV }}/common/users qa_users_passwd | QA_USERS_PASSWD;
secret/dsde/firecloud/${{ inputs.ENV }}/common/users service_acct_email | SERVICE_ACCT_EMAIL;
secret/dsde/firecloud/${{ inputs.ENV }}/common/users users | USERS;
secret/dsde/firecloud/${{ inputs.ENV }}/common/users users_passwd | USERS_PASSWD;


- id: prepare-secrets
name: Prepare secrets
run: |
echo firecloud-json='{"auth_provider_x509_cert_url":"${{ env.FIRECLOUD_ACCOUNT_AUTH_CERT_URL }}","auth_uri":"${{ env.FIRECLOUD_ACCOUNT_AUTH_URI }}","client_email":"${{ env.FIRECLOUD_ACCOUNT_CLIENT_EMAIL }}","client_id":"${{ env.FIRECLOUD_ACCOUNT_CLIENT_ID }}","client_x509_cert_url":"${{ env.FIRECLOUD_ACCOUNT_CLIENT_CERT_URL }}","private_key":${{ toJSON(env.FIRECLOUD_ACCOUNT_PVT_KEY) }},"private_key_id":"${{ env.FIRECLOUD_ACCOUNT_PVT_KEY_ID }}","project_id":"${{ env.FIRECLOUD_ACCOUNT_PROJECT_ID }}","token_uri":"${{ env.FIRECLOUD_ACCOUNT_TOKEN_URI }}","type":"${{ env.FIRECLOUD_ACCOUNT_TYPE }}"}' >> $GITHUB_OUTPUT
echo rawls-json='{"auth_provider_x509_cert_url":"${{ env.RAWLS_ACCOUNT_AUTH_CERT_URL }}","auth_uri":"${{ env.RAWLS_ACCOUNT_AUTH_URI }}","client_email":"${{ env.RAWLS_ACCOUNT_CLIENT_EMAIL }}","client_id":"${{ env.RAWLS_ACCOUNT_CLIENT_ID }}","client_x509_cert_url":"${{ env.RAWLS_ACCOUNT_CLIENT_CERT_URL }}","private_key":${{ toJSON(env.RAWLS_ACCOUNT_PVT_KEY) }},"private_key_id":"${{ env.RAWLS_ACCOUNT_PVT_KEY_ID }}","project_id":"${{ env.RAWLS_ACCOUNT_PROJECT_ID }}","token_uri":"${{ env.RAWLS_ACCOUNT_TOKEN_URI }}","type":"${{ env.RAWLS_ACCOUNT_TYPE }}"}' >> $GITHUB_OUTPUT
echo firecloud-secrets='{"firecloud_id":"${{ env.FIRECLOUD_ID }}"}' >> $GITHUB_OUTPUT
echo firecloud-users='{"automation_users_passwd":"${{ env.AUTOMATION_USERS_PASSWD }}","billing_acct":"${{ env.BILLING_ACCT }}","qa_users_passwd":"${{ env.QA_USERS_PASSWD }}","service_acct_email":"${{ env.SERVICE_ACCT_EMAIL }}","users":${{ toJSON(env.USERS) }},"users_passwd":"${{ env.USERS_PASSWD }}"}' >> $GITHUB_OUTPUT
echo sam-firestore-json='{"auth_provider_x509_cert_url":"${{ env.SAM_FIRESTORE_ACCOUNT_AUTH_CERT_URL }}","auth_uri":"${{ env.SAM_FIRESTORE_ACCOUNT_AUTH_URI }}","client_email":"${{ env.SAM_FIRESTORE_ACCOUNT_CLIENT_EMAIL }}","client_id":"${{ env.SAM_FIRESTORE_ACCOUNT_CLIENT_ID }}","client_x509_cert_url":"${{ env.SAM_FIRESTORE_ACCOUNT_CLIENT_CERT_URL }}","private_key":${{ toJSON(env.SAM_FIRESTORE_ACCOUNT_PVT_KEY) }},"private_key_id":"${{ env.SAM_FIRESTORE_ACCOUNT_PVT_KEY_ID }}","project_id":"${{ env.SAM_FIRESTORE_ACCOUNT_PROJECT_ID }}","token_uri":"${{ env.SAM_FIRESTORE_ACCOUNT_TOKEN_URI }}","type":"${{ env.SAM_FIRESTORE_ACCOUNT_TYPE }}"}' >> $GITHUB_OUTPUT
echo "::add-mask::${{ env.FIRECLOUD_ID }}"
echo "::add-mask::${{ env.AUTOMATION_USERS_PASSWD }}"
echo "::add-mask::${{ env.BILLING_ACCT }}"
echo "::add-mask::${{ env.QA_USERS_PASSWD }}"
echo "::add-mask::${{ env.SERVICE_ACCT_EMAIL }}"
echo "::add-mask::${{ env.USERS }}"
echo "::add-mask::${{ env.USERS_PASSWD }}"

- id: render-secrets
name: Render secrets
run: |
FIRECLOUD_JSON_KEY_B64=$(printf '%s' ${{ toJSON( secrets.FIRECLOUD_JSON_KEY ) }} | base64 -w0)
RAWLS_JSON_KEY_B64=$(printf '%s' ${{ toJSON( secrets.RAWLS_JSON_KEY ) }} | base64 -w0)
FIRECLOUD_SECRETS_B64=$(printf '%s' ${{ toJSON(steps.prepare-secrets.outputs.firecloud-secrets) }} | base64 -w0)
FIRECLOUD_USERS_B64=$(printf '%s' ${{ toJSON(steps.prepare-secrets.outputs.firecloud-users) }} | base64 -w0)

echo "::add-mask::$FIRECLOUD_SECRETS_B64"
echo firecloud-secrets-b64=$FIRECLOUD_SECRETS_B64 >> $GITHUB_OUTPUT
echo "::add-mask::$FIRECLOUD_USERS_B64"
echo firecloud-users-b64=$FIRECLOUD_USERS_B64 >> $GITHUB_OUTPUT

- id: render-secrets-v2
name: Render secrets v2 (eventually replacing render-secrets and getting rid of reliance on sensitive SA keys)
run: |
users_metadata_json_b64=""
if [ -e "users_metadata_json.b64" ]; then
users_metadata_json_b64=$(cat users_metadata_json.b64)
if [ -n "$users_metadata_json_b64" ]; then
echo "::add-mask::$users_metadata_json_b64"
fi
echo $users_metadata_json_b64
fi
echo "users-metadata-json-b64=$users_metadata_json_b64" >> $GITHUB_OUTPUT

- id: run-rawls-swat-tests
name: 'Run Rawls Swat tests'
uses: broadinstitute/dsp-reusable-workflows/.github/actions/run-swat-tests@DDO-3838-swat-test-move
with:
service_repo: ${{ env.SERVICE_REPO }}
ref: ${{ inputs.ref }}
bee_name: ${{ inputs.bee-name }}
broadbot_token: ${{ secrets.BROADBOT_TOKEN }}
firecloud-json-key-b64: ${{ steps.render-secrets.outputs.firecloud-json-key-b64 }}
firecloud-secrets-b64: ${{ steps.render-secrets.outputs.firecloud-secrets-b64 }}
firecloud-users-b64: ${{ steps.render-secrets.outputs.firecloud-users-b64 }}
rawls-json-key-b64: ${{ steps.render-secrets.outputs.rawls-json-key-b64 }}
sam-firestore-json-key-b64: ${{ steps.render-secrets.outputs.sam-firestore-json-key-b64 }}
test-group-name: ${{ inputs.test-group-name }}
sbt-test-command: "${{ inputs.test-command }}"
sbt-test-project: automation
test_run_id: ${{ env.test_run_id }}
test_env: ${{ inputs.ENV }}
java_version: ${{ fromJson(inputs.additional-args).java-version }}
e2e_env: ${{ inputs.e2e-env }}
billing_project: ${{ fromJson(inputs.additional-args).billing-project }}
users-metadata-b64: ${{ steps.render-secrets-v2.outputs.users-metadata-json-b64 }}

- name: Publish Test Report
uses: mikepenz/action-junit-report@v4
if: always()
with:
check_name: report-${{ inputs.test-group-name }}
report_paths: 'rawls/automation/target/test-reports/TEST-*.xml'
fail_on_failure: false
require_tests: false
require_passed_tests: false
annotate_only: true
detailed_summary: true

- name: Store Test Result Artifact
uses: actions/upload-artifact@v3
if: always()
with:
name: test-reports
path: 'rawls/automation/target/test-reports/'

upload-test-results:
needs: [rawls-swat-test-job]
if: ${{ always() && fromJson(inputs.additional-args).logging }} # always run (even in previous steps fail, unless told not to log)
permissions:
contents: 'read'
id-token: 'write'
uses: broadinstitute/dsp-reusable-workflows/.github/workflows/upload_test_results_to_biquery.yaml@main
# Always attempt to run if pull_request, as we want to report the appVersion even if the tests fail.
# never run on cron or other runs as we don't want extranaeous build reporting.
with:
service-name: 'rawls'
test-uuid: ${{ github.run_id }} # run id of this gha
environment: '${{ inputs.test-context }}'
artifact: 'test-reports'
big-query-table: 'broad-dsde-qa.automated_testing.test_results'
subuuid: ${{ github.run_id }} # run id of this gha
Loading