added error codes detection #2651
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build proxy docker image | |
on: | |
workflow_dispatch: | |
inputs: | |
full_test_suite: | |
default: "false" | |
required: true | |
description: "Run full test suite" | |
evm_sha_tag: | |
required: false | |
description: "Neon EVM commit" | |
evm_tag: | |
required: false | |
description: "Neon EVM branch image tag" | |
evm_pr_version_branch: | |
required: false | |
description: "Neon EVM base branch for PR to version branch" | |
initial_pr: | |
required: false | |
description: "Initial PR" | |
pull_request: | |
types: [opened, reopened, synchronize, labeled, unlabeled, ready_for_review] | |
push: | |
branches: | |
- master | |
- develop | |
- '[vt][0-9].[0-9]+.[0-9x]+*' | |
tags: | |
- "*" | |
env: | |
DEFAULT_NEON_EVM_TAG: "latest" | |
DEFAULT_FAUCET_TAG: "latest" | |
AWS_ACCESS_KEY_ID: ${{secrets.AWS_ACCESS_KEY_ID}} | |
AWS_DEFAULT_REGION: ${{secrets.AWS_DEFAULT_REGION}} | |
AWS_SECRET_ACCESS_KEY: ${{secrets.AWS_SECRET_ACCESS_KEY}} | |
DOCKER_USERNAME: ${{secrets.DOCKER_USERNAME}} | |
DOCKER_PASSWORD: ${{secrets.DOCKER_PASSWORD}} | |
BUILD_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
NEON_TEST_IMAGE: ${{vars.DOCKERHUB_ORG_NAME}}/neon_tests | |
TF_VAR_run_number: ${{ github.run_number }} | |
TF_VAR_ci_pp_solana_url: ${{secrets.DEVNET_INTERNAL_RPC}} | |
TF_VAR_neon_evm_commit: "latest" | |
TF_VAR_faucet_model_commit: ${{vars.FAUCET_COMMIT}} | |
TV_VAR_dockerhub_org_name: ${{vars.DOCKERHUB_ORG_NAME}} | |
TF_VAR_proxy_image_name: "neon-proxy.py" | |
HCLOUD_TOKEN: ${{secrets.HCLOUD_TOKEN}} | |
DOCKERHUB_ORG_NAME: ${{vars.DOCKERHUB_ORG_NAME}} | |
PROXY_IMAGE_NAME: "neon-proxy.py" | |
NEON_TESTS_IMAGE: "neon_tests" | |
FAUCET_COMMIT: ${{vars.FAUCET_COMMIT}} | |
GH_ORG_NAME: ${{vars.GH_ORG_NAME}} | |
IMAGE_NAME: ${{vars.IMAGE_NAME}} | |
NEON_TEST_INVOKE_PROGRAM_IMAGE: ${{vars.NEON_TEST_INVOKE_PROGRAM_IMAGE}} | |
NEON_TEST_RUN_LINK: ${{vars.NEON_TEST_RUN_LINK}} | |
NEON_TESTS_ENDPOINT: ${{vars.NEON_TESTS_ENDPOINT}} | |
TFSTATE_BUCKET: ${{vars.TFSTATE_BUCKET}} | |
TFSTATE_KEY_PREFIX: ${{vars.TFSTATE_KEY_PREFIX}} | |
TFSTATE_REGION: ${{vars.TFSTATE_REGION}} | |
GITHUB_RUN_NUMBER: ${{ github.run_number }} | |
TEST_RESULTS_DB_HOST: ${{ secrets.TEST_RESULTS_DB_HOST }} | |
TEST_RESULTS_DB_PORT: ${{ secrets.TEST_RESULTS_DB_PORT }} | |
TEST_RESULTS_DB_NAME: ${{ secrets.TEST_RESULTS_DB_NAME }} | |
TEST_RESULTS_DB_USER: ${{ secrets.TEST_RESULTS_DB_USER }} | |
TEST_RESULTS_DB_PASSWORD: ${{ secrets.TEST_RESULTS_DB_PASSWORD }} | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref }}${{ github.event.inputs.evm_sha_tag }} | |
cancel-in-progress: true | |
jobs: | |
build-image: | |
runs-on: build-runner | |
outputs: | |
proxy_tag: ${{ steps.tags.outputs.proxy_tag }} | |
proxy_sha_tag: ${{ steps.tags.outputs.proxy_sha_tag }} | |
proxy_pr_version_branch: ${{ steps.tags.outputs.proxy_pr_version_branch }} | |
is_proxy_release: ${{ steps.tags.outputs.is_proxy_release }} | |
evm_tag: ${{ steps.tags.outputs.evm_tag }} | |
evm_sha_tag: ${{ steps.tags.outputs.evm_sha_tag }} | |
evm_pr_version_branch: ${{ steps.tags.outputs.evm_pr_version_branch }} | |
faucet_tag: ${{ steps.tags.outputs.faucet_tag }} | |
neon_test_tag: ${{ steps.tags.outputs.neon_test_tag }} | |
full_test_suite: ${{ steps.full_test_suite.outputs.value }} | |
dapps_list: ${{ steps.dapps_list.outputs.dapps_list }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: output branches name | |
run: | | |
echo "neon_evm_tag/branch = ${{ github.event.inputs.evm_tag }}" | |
echo "proxy_branch = ${{ github.ref }}" | |
- name: Specify image tags | |
run: | | |
python3 ./.github/workflows/deploy.py specify_image_tags \ | |
--git_sha=${{ github.sha }} \ | |
--git_ref=${{ github.ref }} \ | |
--git_head_ref=${{ github.head_ref }} \ | |
--git_base_ref=${{ github.base_ref }} \ | |
--evm_sha_tag=${{ github.event.inputs.evm_sha_tag }} \ | |
--evm_tag=${{ github.event.inputs.evm_tag }} \ | |
--default_evm_tag=${DEFAULT_NEON_EVM_TAG} \ | |
--default_faucet_tag=${DEFAULT_FAUCET_TAG} | |
- name: Set outputs | |
id: tags | |
run: | | |
echo "proxy_tag=${{ env.PROXY_TAG }}" >> "$GITHUB_OUTPUT" | |
echo "proxy_sha_tag=${{ env.PROXY_SHA_TAG }}" >> "$GITHUB_OUTPUT" | |
echo "proxy_pr_version_branch=${{ env.PROXY_PR_VERSION_BRANCH }}" >> "$GITHUB_OUTPUT" | |
echo "is_proxy_release=${{ env.IS_PROXY_RELEASE }}" >> "$GITHUB_OUTPUT" | |
echo "evm_tag=${{ env.EVM_TAG }}" >> "$GITHUB_OUTPUT" | |
echo "evm_sha_tag=${{ env.EVM_SHA_TAG }}" >> "$GITHUB_OUTPUT" | |
echo "evm_pr_version_branch=${{ github.event.inputs.evm_pr_version_branch }}" >> "$GITHUB_OUTPUT" | |
echo "faucet_tag=${{ env.FAUCET_TAG }}" >> "$GITHUB_OUTPUT" | |
echo "neon_test_tag=${{ env.NEON_TEST_TAG }}" >> "$GITHUB_OUTPUT" | |
- name: Define test set | |
id: full_test_suite | |
run: | | |
if [[ "${{ contains(github.event.pull_request.labels.*.name, 'fullTestSuite') }}" == "true" || "${{ github.event.inputs.full_test_suite }}" == "true" || | |
("${{ github.ref_name }}" == 'develop' && "${{github.event.inputs.evm_sha_tag }}" == "") || | |
"${{ steps.tags.outputs.is_proxy_release }}" == "True" || "${{ steps.tags.outputs.proxy_pr_version_branch }}" != "" ]]; then | |
value=true | |
else | |
value=false | |
fi; | |
echo "value=${value}" | |
echo "value=${value}" >> $GITHUB_OUTPUT | |
- name: Define dapps tests list | |
id: dapps_list | |
run: | | |
default="aave-v2,saddle,uniswap-v3" | |
extended=",uniswap-v2,yearn,compound,robonomics,curve,saddle,pancake" | |
result=$( (${{ steps.full_test_suite.outputs.value }} && echo "${default}${extended}") || echo "${default}" ) | |
echo "dapps_list=$result" >> $GITHUB_OUTPUT | |
echo "dapps_list=$result" | |
- name: Build docker image | |
run: | | |
python3 ./.github/workflows/deploy.py build_docker_image \ | |
--evm_tag=${{ steps.tags.outputs.evm_sha_tag || steps.tags.outputs.evm_tag }} \ | |
--proxy_tag=${{ steps.tags.outputs.proxy_sha_tag }} | |
- name: Publish image | |
run: | | |
python3 ./.github/workflows/deploy.py publish_image \ | |
--proxy_sha_tag=${{ steps.tags.outputs.proxy_sha_tag }} \ | |
--proxy_tag=${{ steps.tags.outputs.proxy_tag }} | |
deploy-check: | |
needs: | |
- build-image | |
runs-on: test-runner | |
steps: | |
- uses: actions/checkout@v4 | |
- name: deploy_check | |
timeout-minutes: 60 | |
run: | | |
python3 ./.github/workflows/deploy.py deploy_check \ | |
--proxy_tag=${{ needs.build-image.outputs.proxy_sha_tag }} | |
- name: canceling the build if job failed | |
if: "failure()" | |
uses: "andymckay/[email protected]" | |
prepare-infrastructure: | |
needs: | |
- build-image | |
timeout-minutes: 15 | |
runs-on: test-runner | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Add private key | |
run: | | |
echo "${{ secrets.CI_STANDS_KEY_HCLOUD }}" > ${HOME}/.ssh/ci-stands | |
chmod 600 ${HOME}/.ssh/ci-stands | |
- name: Remove known_host | |
run: rm -f ${HOME}/.ssh/known_hosts | |
- name: Terraform build infrastructure | |
id: terraform | |
run: | | |
python3 ./.github/workflows/deploy.py terraform_infrastructure \ | |
--proxy_tag=${{ needs.build-image.outputs.proxy_sha_tag }} \ | |
--evm_tag=${{ needs.build-image.outputs.evm_sha_tag || needs.build-image.outputs.evm_tag }} \ | |
--faucet_tag=${{ needs.build-image.outputs.faucet_tag }} \ | |
--run_number=${{ env.GITHUB_RUN_NUMBER }} | |
- name: Set outputs | |
id: share | |
env: | |
SOLANA_IP: ${{ env.SOLANA_IP }} | |
PROXY_IP: ${{ env.PROXY_IP }} | |
run: | | |
echo "solana_ip=${{ env.SOLANA_IP }}" >> $GITHUB_OUTPUT | |
echo "proxy_ip=${{ env.PROXY_IP }}" >> $GITHUB_OUTPUT | |
- uses: actions/upload-artifact@v4 | |
if: always() | |
with: | |
name: Terraform infrastructure logs | |
path: ./terraform.log | |
outputs: | |
solana_ip: ${{ steps.share.outputs.solana_ip }} | |
proxy_ip: ${{ steps.share.outputs.proxy_ip }} | |
openzeppelin-tests: | |
if: needs.build-image.outputs.full_test_suite=='true' | |
needs: | |
- prepare-infrastructure | |
- build-image | |
runs-on: test-runner | |
env: | |
SOLANA_IP: ${{ needs.prepare-infrastructure.outputs.solana_ip }} | |
PROXY_IP: ${{ needs.prepare-infrastructure.outputs.proxy_ip }} | |
CONTAINER: oz-${{ github.run_id }} | |
NETWORK: terraform | |
steps: | |
- name: Pull docker image | |
run: docker pull ${{ env.NEON_TEST_IMAGE }}:${{ needs.build-image.outputs.neon_test_tag }} | |
- name: Run docker container | |
run: | | |
docker run -i -e PROXY_IP=${{env.PROXY_IP}} \ | |
-e SOLANA_IP=${{env.SOLANA_IP}} \ | |
-e NETWORK=${{env.NETWORK}} \ | |
-d --name=${{ env.CONTAINER }} ${{ env.NEON_TEST_IMAGE }}:${{ needs.build-image.outputs.neon_test_tag }} /bin/bash | |
- name: Run OpenZeppelin tests | |
run: | | |
docker exec -i -e PROXY_IP=${{env.PROXY_IP}} \ | |
-e SOLANA_IP=${{env.SOLANA_IP}} \ | |
-e NETWORK=${{env.NETWORK}} \ | |
${{ env.CONTAINER }} python3 ./clickfile.py run oz \ | |
--network ${{ env.NETWORK }} \ | |
--jobs 8 \ | |
--users 10 | |
- name: Print OpenZeppelin report | |
run: | | |
docker exec -i ${{ env.CONTAINER }} python3 ./clickfile.py oz report | |
- name: Analyze tests results | |
run: | | |
docker exec -i ${{ env.CONTAINER }} python3 ./clickfile.py oz analyze | |
- name: "Archive report" | |
if: always() | |
run: | | |
docker exec -i ${{ env.CONTAINER }} tar -czvf ./allure-results.tar.gz /opt/neon-tests/allure-results | |
docker cp ${{ env.CONTAINER }}:/opt/neon-tests/allure-results.tar.gz ./ | |
- uses: actions/upload-artifact@v4 | |
if: always() | |
with: | |
name: FTS allure report | |
path: allure-results.tar.gz | |
- name: Remove docker container | |
if: always() | |
run: docker rm -f ${{ env.CONTAINER }} | |
- name: canceling the build if job failed | |
if: "failure()" | |
uses: "andymckay/[email protected]" | |
basic-tests: | |
needs: | |
- prepare-infrastructure | |
- build-image | |
runs-on: test-runner | |
env: | |
SOLANA_IP: ${{ needs.prepare-infrastructure.outputs.solana_ip }} | |
PROXY_IP: ${{ needs.prepare-infrastructure.outputs.proxy_ip }} | |
NUMPROCESSES: 12 | |
CONTAINER: basic-${{ github.run_id }} | |
NETWORK: terraform | |
steps: | |
- name: Determine Cost Report Generation | |
run: | | |
echo "GENERATE_COST_REPORT=true" >> $GITHUB_ENV | |
- name: Run docker container | |
run: | | |
image="${{ env.NEON_TEST_IMAGE }}:${{ needs.build-image.outputs.neon_test_tag }}" | |
docker pull $image | |
docker run -i -d -e PROXY_IP=${{ env.PROXY_IP }} -e SOLANA_IP=${{ env.SOLANA_IP }} \ | |
--name=${{ env.CONTAINER }} $image /bin/bash | |
- name: Run basic tests | |
run: | | |
CMD="python3 ./clickfile.py run basic --network ${{ env.NETWORK }} --numprocesses ${{ env.NUMPROCESSES }}" | |
if [[ "${{ env.GENERATE_COST_REPORT }}" == "true" ]]; then | |
CMD="$CMD --cost_reports_dir reports/cost_reports" | |
fi | |
docker exec -i ${{ env.CONTAINER }} $CMD | |
- name: Copy cost reports from container | |
if: ${{ env.GENERATE_COST_REPORT == 'true' }} | |
run: | | |
mkdir -p ./reports/cost_reports/ && \ | |
docker cp ${{ env.CONTAINER }}:/opt/neon-tests/reports/cost_reports/. ./reports/cost_reports/ | |
- name: Upload cost reports as artifacts | |
if: ${{ env.GENERATE_COST_REPORT == 'true' }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: cost-reports | |
path: reports/cost_reports/**.json | |
- name: Swap Cost Reports and echo to Summary | |
if: ${{ env.GENERATE_COST_REPORT == 'true' }} | |
run: | | |
docker exec -i -e NETWORK=${{ env.NETWORK }} ${{ env.CONTAINER }} \ | |
python3 ./clickfile.py dapps save_dapps_cost_report_to_md \ | |
--directory reports/cost_reports && \ | |
docker exec -i ${{ env.CONTAINER }} cat cost_reports.md >> $GITHUB_STEP_SUMMARY | |
- name: "Save Cost Report to DB" | |
id: save-cost-report-to-db | |
if: ${{ env.GENERATE_COST_REPORT == 'true' }} | |
run: | | |
docker exec -i \ | |
-e NETWORK=${{ env.NETWORK }} \ | |
-e TEST_RESULTS_DB_HOST=${{ env.TEST_RESULTS_DB_HOST }} \ | |
-e TEST_RESULTS_DB_PORT=${{ env.TEST_RESULTS_DB_PORT }} \ | |
-e TEST_RESULTS_DB_NAME=${{ env.TEST_RESULTS_DB_NAME }} \ | |
-e TEST_RESULTS_DB_USER=${{ env.TEST_RESULTS_DB_USER }} \ | |
-e TEST_RESULTS_DB_PASSWORD=${{ env.TEST_RESULTS_DB_PASSWORD }} \ | |
${{ env.CONTAINER }} \ | |
python3 ./clickfile.py dapps save_dapps_cost_report_to_db \ | |
--directory="reports/cost_reports" \ | |
--repo="${{ needs.build-image.outputs.evm_sha_tag == '' && 'proxy' || 'evm' }}" \ | |
--evm_tag="${{ needs.build-image.outputs.evm_tag }}" \ | |
--proxy_tag="${{ needs.build-image.outputs.proxy_tag }}" \ | |
--evm_commit_sha="${{ needs.build-image.outputs.evm_sha_tag }}" \ | |
--proxy_commit_sha="${{ needs.build-image.outputs.proxy_sha_tag }}" | |
- name: Remove docker container | |
if: always() | |
run: docker rm -f ${{ env.CONTAINER }} | |
- name: canceling the build if job failed | |
if: "failure()" | |
uses: "andymckay/[email protected]" | |
dapps-tests: | |
needs: | |
- prepare-infrastructure | |
- build-image | |
uses: neonlabsorg/neon-tests/.github/workflows/dapps_reusable.yml@develop | |
secrets: inherit | |
with: | |
network: custom | |
dapps: ${{ needs.build-image.outputs.dapps_list }} | |
proxy_url: "http://${{ needs.prepare-infrastructure.outputs.proxy_ip }}:9090/solana" | |
solana_url: "http://${{ needs.prepare-infrastructure.outputs.solana_ip }}:8899/" | |
faucet_url: "http://${{ needs.prepare-infrastructure.outputs.proxy_ip }}:3333/" | |
network_id: "111" | |
pr_url_for_report: ${{ github.event.inputs.initial_pr }} | |
proxy_ip: ${{ needs.prepare-infrastructure.outputs.proxy_ip }} | |
solana_ip: ${{ needs.prepare-infrastructure.outputs.solana_ip }} | |
external_call: true | |
repo: ${{ needs.build-image.outputs.evm_sha_tag == '' && 'proxy' || 'evm' }} | |
evm_tag: ${{ needs.build-image.outputs.evm_tag }} | |
evm_sha_tag: ${{ needs.build-image.outputs.evm_sha_tag }} | |
proxy_tag: ${{ needs.build-image.outputs.proxy_tag }} | |
proxy_sha_tag: ${{ needs.build-image.outputs.proxy_sha_tag }} | |
proxy_pr_version_branch: ${{ needs.build-image.outputs.proxy_pr_version_branch }} | |
evm_pr_version_branch: ${{ needs.build-image.outputs.evm_pr_version_branch }} | |
requests-report: | |
needs: | |
- prepare-infrastructure | |
- basic-tests | |
- build-image | |
- dapps-tests | |
- openzeppelin-tests | |
if: | | |
always() && | |
contains(fromJSON('["success", "skipped"]'), needs.openzeppelin-tests.result) && | |
contains(fromJSON('["success", "skipped"]'), needs.dapps-tests.result) | |
runs-on: test-runner | |
env: | |
SOLANA_IP: ${{ needs.prepare-infrastructure.outputs.solana_ip }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Request report | |
id: request_report | |
run: | | |
stats=$(python3 ./.github/workflows/deploy.py parse_logs --solana_ip=${{ env.SOLANA_IP }}) | |
echo "stats<<EOF" >> $GITHUB_OUTPUT | |
echo "$stats" >> $GITHUB_OUTPUT | |
echo "EOF" >> $GITHUB_OUTPUT | |
echo "stats=$stats" | |
if [[ "${{ github.event.inputs.initial_pr }}" != "" ]]; then | |
echo "pull_request=${{ github.event.inputs.initial_pr }}" >> $GITHUB_OUTPUT | |
else | |
echo "pull_request=${{ github.event.pull_request.issue_url }}/comments" >> $GITHUB_OUTPUT | |
fi; | |
- name: "Post a comment with the report" | |
run: | | |
python3 ./.github/workflows/deploy.py post_comment --message="${{ steps.request_report.outputs.stats }}" \ | |
--pull_request="${{ steps.request_report.outputs.pull_request }}" \ | |
--token=${{ secrets.GHTOKEN }} | |
destroy-terraform: | |
needs: | |
- prepare-infrastructure | |
- openzeppelin-tests | |
- basic-tests | |
- requests-report | |
- dapps-tests | |
- build-image | |
runs-on: test-runner | |
if: always() | |
env: | |
SOLANA_IP: ${{ needs.prepare-infrastructure.outputs.solana_ip }} | |
PROXY_IP: ${{ needs.prepare-infrastructure.outputs.proxy_ip }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Add private key | |
run: | | |
echo "${{ secrets.CI_STANDS_KEY_HCLOUD }}" > ${HOME}/.ssh/ci-stands | |
chmod 644 ${HOME}/.ssh/ci-stands | |
- name: Get container logs | |
if: always() | |
run: python3 ./.github/workflows/deploy.py get_container_logs | |
- uses: actions/upload-artifact@v4 | |
if: always() | |
with: | |
name: FTS docker logs | |
path: ./logs/* | |
- name: Set output | |
id: vars | |
run: echo "bname=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT | |
- name: Destroy terraform infrastructure | |
if: ${{always() && needs.prepare-infrastructure.result != 'skipped'}} | |
run: | | |
python3 ./.github/workflows/deploy.py destroy_terraform \ | |
--run_number=${{env.GITHUB_RUN_NUMBER}} \ | |
--proxy_tag=${{ needs.build-image.outputs.proxy_sha_tag }} | |
finalize-image: | |
runs-on: build-runner | |
needs: | |
- build-image | |
- openzeppelin-tests | |
- basic-tests | |
- dapps-tests | |
- deploy-check | |
if: | | |
always() && | |
needs.deploy-check.result == 'success' && | |
needs.basic-tests.result == 'success' && | |
needs.dapps-tests.result == 'success' && | |
contains(fromJSON('["success", "skipped"]'), needs.openzeppelin-tests.result) | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Tag published image if tag is latest or version | |
run: | | |
python3 ./.github/workflows/deploy.py finalize_image \ | |
--proxy_sha_tag=${{ needs.build-image.outputs.proxy_sha_tag }} \ | |
--proxy_tag=${{ needs.build-image.outputs.proxy_tag }} | |
notification: | |
runs-on: build-runner | |
needs: | |
- finalize-image | |
- openzeppelin-tests | |
- basic-tests | |
- dapps-tests | |
- deploy-check | |
- build-image | |
if: | | |
failure() && needs.build-image.outputs.full_test_suite == 'true' | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Send notification to slack | |
run: | | |
python3 ./.github/workflows/deploy.py send_notification \ | |
--url=${{secrets.SLACK_PROXY_CHANNEL_URL}} \ | |
--build_url=${BUILD_URL} |