Add certification test workflow (#1242)

This commit is contained in:
Simon Leet 2021-10-29 13:36:03 -07:00 committed by GitHub
parent 8a6f7dfdc5
commit 62d17de1fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 237 additions and 0 deletions

230
.github/workflows/certification.yml vendored Normal file
View File

@ -0,0 +1,230 @@
# ------------------------------------------------------------
# Copyright (c) Microsoft Corporation and Dapr Contributors.
# Licensed under the MIT License.
# ------------------------------------------------------------
name: Stable Components Certification Tests
on:
repository_dispatch:
types: [certification-test]
workflow_dispatch:
schedule:
- cron: '*/30 * * * *'
pull_request:
branches:
- master
- release-*
jobs:
pre_job:
name: Skip Duplicate Actions
runs-on: ubuntu-latest
outputs:
should_skip: ${{ steps.skip_check.outputs.should_skip }}
steps:
- id: skip_check
uses: fkirc/skip-duplicate-actions@v3.4.0
with:
cancel_others: 'true'
paths_ignore: '["**.md", ".codecov.yaml", ".github/workflows/dapr-automerge.yml"]'
# Based on whether this is a PR or a scheduled run, we will run a different
# subset of the certification tests. This allows all the tests not requiring
# secrets to be executed on pull requests.
generate-matrix:
runs-on: ubuntu-latest
needs: pre_job
if: needs.pre_job.outputs.should_skip != 'true'
steps:
- name: Install yq
run: |
sudo snap install yq
- name: Specify components that can be run on every PR
id: pr-components
run: |
PR_COMPONENTS=$(yq -I0 --tojson eval - << EOF
- pubsub.kafka
EOF
)
echo "::set-output name=pr-components::$PR_COMPONENTS"
- name: Specify components requiring cloud resources to run
id: cloud-components
run: |
# Skip cloud-components on PRs, requires scheduled run trigger
# or approver to trigger via respository-dispatch on /ok-to-test
if [ "${{ github.event_name }}" = "pull_request" ]; then
echo "::set-output name=cloud-components::[]"
exit
fi
# Reuse the same cloud infrastructure as conformance.yml
#
# Unfortunately, Azure secrets can't have underscores in
# names, while environment variables with hyphens ('-') are
# troublesome.
#
# We work around here by leveraging the fact that
# environment variable names are case sensitive, so
# CamelCase would still work.
#
# That is slightly better than something like
# AZURECOSMOSDBMASTERKEY, which is extremely hard to read
# and errorprone.
#
# Only list the secrets you need for the component.
CRON_COMPONENTS=$(yq -I0 --tojson eval - << EOF
- component: secretstores.azure.keyvault
required-secrets: AzureKeyVaultName,AzureKeyVaultSecretStoreTenantId,AzureKeyVaultSecretStoreClientId,AzureKeyVaultSecretStoreServicePrincipalClientId,AzureKeyVaultSecretStoreServicePrincipalClientSecret
required-certs: AzureKeyVaultSecretStoreCert
EOF
)
echo "::set-output name=cloud-components::$CRON_COMPONENTS"
outputs:
pr-components: ${{ steps.pr-components.outputs.pr-components }}
cloud-components: ${{ steps.cloud-components.outputs.cloud-components }}
certification:
name: ${{ matrix.component }} certification
runs-on: ubuntu-latest
defaults:
run:
shell: bash
working-directory: ./src/github.com/dapr/components-contrib
needs: generate-matrix
strategy:
fail-fast: false # Keep running even if one component fails
matrix:
component: ${{ fromJson(needs.generate-matrix.outputs.pr-components) }}
include: ${{ fromJson(needs.generate-matrix.outputs.cloud-components) }}
steps:
- name: Parse repository_dispatch payload
if: github.event_name == 'repository_dispatch'
uses: actions/github-script@v1
with:
github-token: ${{secrets.DAPR_BOT_TOKEN}}
script: |
const testPayload = context.payload.client_payload;
if (testPayload && testPayload.command == "ok-to-test") {
var fs = require('fs');
// Set environment variables
fs.appendFileSync(process.env.GITHUB_ENV,
`CHECKOUT_REPO=${testPayload.pull_head_repo}\n`+
`CHECKOUT_REF=${testPayload.pull_head_ref}`);
}
- name: Check out code onto GOPATH
uses: actions/checkout@v2
with:
path: ./src/github.com/dapr/components-contrib
- name: Setup test output
shell: bash
run: |
export TEST_OUTPUT_FILE_PREFIX=$GITHUB_WORKSPACE/test_report
echo "TEST_OUTPUT_FILE_PREFIX=$TEST_OUTPUT_FILE_PREFIX" >> $GITHUB_ENV
- name: Configure certification test path
run: |
TEST_COMPONENT=$(echo ${{ matrix.component }} | sed -E 's/\./\//g')
export TEST_PATH="./src/github.com/dapr/components-contrib/tests/certification/${TEST_COMPONENT}"
echo "TEST_PATH=$TEST_PATH" >> $GITHUB_ENV
- uses: Azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
if: matrix.required-secrets != ''
- name: Setup secrets
uses: Azure/get-keyvault-secrets@v1
with:
# Set this GitHub secret to your KeyVault, and grant the KeyVault policy to your Service Principal:
# az keyvault set-policy -n $AZURE_KEYVAULT --secret-permissions get list --spn $SPN_CLIENT_ID
keyvault: ${{ secrets.AZURE_KEYVAULT }}
secrets: ${{ matrix.required-secrets }}
id: get-azure-secrets
if: matrix.required-secrets != ''
# Download the required certificates into files, and set env var pointing to their names
- name: Setup certs
if: matrix.required-certs != ''
working-directory: ${{ env.TEST_PATH }}
run: |
for CERT_NAME in $(echo "${{ matrix.required-certs }}" | sed 's/,/ /g'); do
CERT_FILE=$(mktemp --suffix .pfx)
echo "Downloading cert $CERT_NAME into file $CERT_FILE"
rm $CERT_FILE && \
az keyvault secret download --vault-name ${{ secrets.AZURE_KEYVAULT }} --name $CERT_NAME --encoding base64 --file $CERT_FILE
echo 'Setting $CERT_NAME to' "$CERT_FILE"
echo "$CERT_NAME=$CERT_FILE" >> $GITHUB_ENV
done
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: '^1.17'
- name: Download Go dependencies
run: |
go mod download
go install gotest.tools/gotestsum@latest
- name: Check that go mod tidy is up-to-date
working-directory: ${{ env.TEST_PATH }}
run: |
go mod tidy
git diff --exit-code ./go.mod
git diff --exit-code ./go.sum
- name: Run tests
continue-on-error: true
working-directory: ${{ env.TEST_PATH }}
run: |
echo "Running certification tests for ${{ matrix.component }} ... "
set +e
gotestsum --jsonfile ${{ env.TEST_OUTPUT_FILE_PREFIX }}_certification.json \
--junitfile ${{ env.TEST_OUTPUT_FILE_PREFIX }}_certification.xml --format standard-verbose -- \
-count=1 -timeout=15m
status=$?
echo "Completed certification tests for ${{ matrix.component }} ... "
if test $status -ne 0; then
echo "Setting CERTIFICATION_FAILURE"
echo "CERTIFICATION_FAILURE=true" >> $GITHUB_ENV
fi
set -e
# Fail the step if we found no test to run
if grep -q "\[no test files\]" ${{ env.TEST_OUTPUT_FILE_PREFIX }}_certification.json ; then
echo "::error:: No certification test file was found for component ${{ matrix.component }}"
exit -1
fi
# Delete any certs downloaded locally
- name: Clean up certs
if: matrix.required-certs != ''
run: |
for CERT_NAME in $(echo "${{ matrix.required-certs }}" | sed 's/,/ /g'); do
CERT_FILE=$(printenv $CERT_NAME)
echo "Cleaning up the certificate file $CERT_FILE..."
rm $CERT_FILE
done
- name: Check certification test passed
continue-on-error: false
run: |
echo "CERTIFICATION_FAILURE=$CERTIFICATION_FAILURE"
if [[ -v CERTIFICATION_FAILURE ]]; then
exit 1
fi
# Upload logs for test analytics to consume
- name: Upload test results
if: always()
uses: actions/upload-artifact@master
with:
name: ${{ matrix.component }}_certification_test
path: ${{ env.TEST_OUTPUT_FILE_PREFIX }}_certification.*

View File

@ -41,6 +41,13 @@ jobs:
event_type: "conformance-test",
client_payload: testPayload,
});
// Fire repository_dispatch event to trigger certification test
await github.repos.createDispatchEvent({
owner: issue.owner,
repo: issue.repo,
event_type: "certification-test",
client_payload: testPayload,
});
}
}
}