diff --git a/.github/workflows/flow-build-application.yaml b/.github/workflows/flow-build-application.yaml new file mode 100644 index 00000000..9b0f7c3d --- /dev/null +++ b/.github/workflows/flow-build-application.yaml @@ -0,0 +1,91 @@ +## +# Copyright (C) 2022-2023 Hedera Hashgraph, LLC +# +# 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. +## + +name: 'Build Application' +on: + workflow_dispatch: + inputs: + enable-unit-tests: + description: 'Unit Testing Enabled' + type: boolean + required: false + default: true + enable-e2e-tests: + description: 'E2E Testing Enabled' + type: boolean + required: false + default: false + enable-snyk-scan: + description: 'Snyk Scan Enabled' + type: boolean + required: false + default: false + push: + branches: + - main + - 'release/*' + +defaults: + run: + shell: bash + +jobs: + code: + name: Code + uses: ./.github/workflows/zxc-compile-code.yaml + + code-style: + name: Code Style + uses: ./.github/workflows/zxc-compile-code.yaml + needs: + - code + with: + custom-job-label: Check + enable-code-style-check: true + + unit-tests: + name: Unit Tests + uses: ./.github/workflows/zxc-compile-code.yaml + if: ${{ github.event_name == 'push' || github.event.inputs.enable-unit-tests == 'true' }} + with: + custom-job-label: Standard + enable-unit-tests: true + + e2e-tests: + name: E2E Tests + uses: ./.github/workflows/zxc-compile-code.yaml + if: ${{ github.event_name == 'push' || github.event.inputs.enable-e2e-tests == 'true' }} + with: + custom-job-label: Standard + enable-e2e-tests: true + + analyze: + name: Analyze + uses: ./.github/workflows/zxc-code-analysis.yaml + needs: + - unit-tests + - e2e-tests + if: ${{ (github.event_name == 'push' || github.event.inputs.enable-unit-tests == 'true' || github.event.inputs.enable-e2e-tests == 'true') && !failure() && !cancelled() }} + with: + custom-job-label: Source Code + #enable-snyk-scan: ${{ github.event_name == 'push' || github.event.inputs.enable-snyk-scan == 'true' }} + enable-codecov-analysis: true + enable-codacy-coverage: true + enable-e2e-coverage-report: ${{ github.event_name == 'push' || github.event.inputs.enable-e2e-tests == 'true' }} + secrets: + snyk-token: ${{ secrets.SNYK_TOKEN }} + codecov-token: ${{ secrets.CODECOV_TOKEN }} + codacy-project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} diff --git a/.github/workflows/flow-pull-request-checks.yaml b/.github/workflows/flow-pull-request-checks.yaml new file mode 100644 index 00000000..84f3a050 --- /dev/null +++ b/.github/workflows/flow-pull-request-checks.yaml @@ -0,0 +1,104 @@ +## +# Copyright (C) 2023-2024 Hedera Hashgraph, LLC +# +# 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. +## + +name: 'PR Checks' +on: + workflow_dispatch: + pull_request: + types: + - opened + - reopened + - synchronize + +defaults: + run: + shell: bash + +concurrency: + group: pr-checks-${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + build: + name: Code + uses: ./.github/workflows/zxc-compile-code.yaml + + code-style: + name: Code Style + uses: ./.github/workflows/zxc-compile-code.yaml + needs: + - build + with: + custom-job-label: Check + enable-code-style-check: true + + unit-tests: + name: Unit Tests + uses: ./.github/workflows/zxc-compile-code.yaml + needs: + - code-style + with: + custom-job-label: Standard + enable-unit-tests: true + + e2e-tests: + name: E2E Tests + uses: ./.github/workflows/zxc-compile-code.yaml + needs: + - code-style + with: + custom-job-label: Standard + enable-e2e-tests: true + + codecov: + name: CodeCov + uses: ./.github/workflows/zxc-code-analysis.yaml + needs: + - unit-tests + - e2e-tests + if: ${{ github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name && github.actor != 'dependabot[bot]' }} + with: + custom-job-label: Standard + enable-codecov-analysis: true + enable-e2e-coverage-report: true + secrets: + codecov-token: ${{ secrets.CODECOV_TOKEN }} + + codacy-coverage: + name: Codacy + uses: ./.github/workflows/zxc-code-analysis.yaml + needs: + - unit-tests + - e2e-tests + if: ${{ github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name && github.actor != 'dependabot[bot]' }} + with: + custom-job-label: Coverage + enable-codacy-coverage: true + enable-e2e-coverage-report: true + secrets: + codacy-project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} +# snyk: +# name: Snyk Scan +# uses: ./.github/workflows/zxc-code-analysis.yaml +# needs: +# - unit-tests +# - e2e-tests +# if: ${{ github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name && github.actor != 'dependabot[bot]' }} +# with: +# custom-job-label: Standard +# enable-snyk-scan: true +# secrets: +# snyk-token: ${{ secrets.SNYK_TOKEN }} diff --git a/.github/workflows/zxc-code-analysis.yaml b/.github/workflows/zxc-code-analysis.yaml new file mode 100644 index 00000000..2cd95286 --- /dev/null +++ b/.github/workflows/zxc-code-analysis.yaml @@ -0,0 +1,183 @@ +## +# Copyright (C) 2023-2024 Hedera Hashgraph, LLC +# +# 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. +## + +name: 'ZXC: Code Analysis' +# The purpose of this reusable workflow is to perform static code analysis and code coverage reporting. +# This reusable component is called by the following workflows: +# - .github/workflows/flow-pull-request-checks.yaml +# - .github/workflows/flow-build-application.yaml +# +# This workflow is only run if the pull request is coming from the original repository and not a fork. + +on: + workflow_call: + inputs: + enable-codecov-analysis: + description: 'CodeCov Analysis Enabled' + type: boolean + required: false + default: false + enable-codacy-coverage: + description: 'Codacy Coverage Enabled' + type: boolean + required: false + default: false + enable-e2e-coverage-report: + description: 'E2E Coverage Report Enabled' + type: boolean + required: false + default: false + enable-snyk-scan: + description: 'Snyk Scan Enabled' + type: boolean + required: false + default: false + node-version: + description: 'NodeJS Version:' + type: string + required: false + default: '20' + custom-job-label: + description: 'Custom Job Label:' + type: string + required: false + default: 'Analyze' + secrets: + snyk-token: + description: 'The Snyk access token is used by Snyk to analyze the code for vulnerabilities ' + required: false + codecov-token: + description: 'The CodeCov access token is used by CodeCov.io to analyze the code coverage ' + required: false + codacy-project-token: + description: 'The Codacy project token used to report code coverage.' + required: false + +defaults: + run: + shell: bash + +permissions: + contents: read + actions: read + pull-requests: write + checks: write + statuses: write + +jobs: + analyze: + name: ${{ inputs.custom-job-label || 'Analyze' }} + runs-on: [self-hosted, Linux, medium, ephemeral] + steps: + - name: Checkout Code + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + ref: ${{ github.event.workflow_run.head_branch }} + fetch-depth: ${{ inputs.enable-sonar-analysis && '0' || '' }} + + - name: Setup Node + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: ${{ inputs.node-version }} + + - name: Download Unit Test Coverage Report + uses: actions/download-artifact@87c55149d96e628cc2ef7e6fc2aab372015aec85 # v4.1.3 + if: ${{ (inputs.enable-codecov-analysis || inputs.enable-codacy-coverage) && !cancelled() && !failure() }} + with: + name: Unit Test Coverage Report + path: 'coverage/unit' + + - name: Download E2E Coverage Report + uses: actions/download-artifact@87c55149d96e628cc2ef7e6fc2aab372015aec85 # v4.1.3 + if: ${{ (inputs.enable-codecov-analysis || inputs.enable-codacy-coverage) && inputs.enable-e2e-coverage-report && !cancelled() && !failure() }} + with: + name: E2E Coverage Report + path: 'coverage/e2e' + + - name: Publish To Codecov + uses: codecov/codecov-action@54bcd8715eee62d40e33596ef5e8f0f48dbbccab # v4.1.0 + if: ${{ inputs.enable-codecov-analysis && !cancelled() && !failure() }} + env: + CODECOV_TOKEN: ${{ secrets.codecov-token }} + with: + verbose: true + directory: 'coverage' + + - name: Publish to Codacy + env: + CODACY_PROJECT_TOKEN: ${{ secrets.codacy-project-token }} + if: ${{ inputs.enable-codacy-coverage && !cancelled() && !failure() }} + run: bash <(curl -Ls https://coverage.codacy.com/get.sh) report -l Javascript $(find . -name 'lcov.info' -printf '-r %p ') + + - name: Setup Snyk + env: + SNYK_TOKEN: ${{ secrets.snyk-token }} + if: ${{ inputs.enable-snyk-scan && !cancelled() && !failure() }} + run: npm install -g snyk snyk-to-html @wcj/html-to-markdown-cli + + - name: Snyk Scan + id: snyk + env: + SNYK_TOKEN: ${{ secrets.snyk-token }} + if: ${{ inputs.enable-snyk-scan && !cancelled() && !failure() }} + run: snyk test --org=release-engineering-N6EoZVZn3jw4qNuVkiG5Qs --all-projects --severity-threshold=high --json-file-output=snyk-test.json + + - name: Snyk Code + id: snyk-code + env: + SNYK_TOKEN: ${{ secrets.snyk-token }} + if: ${{ inputs.enable-snyk-scan && !cancelled() && !failure() }} + run: snyk code test --org=release-engineering-N6EoZVZn3jw4qNuVkiG5Qs --severity-threshold=high --json-file-output=snyk-code.json + + - name: Publish Snyk Results + if: ${{ inputs.enable-snyk-scan && !cancelled() && !failure() }} + run: | + if [[ -f "snyk-test.json" && -n "$(cat snyk-test.json | tr -d '[:space:]')" ]]; then + snyk-to-html -i snyk-test.json -o snyk-test.html --summary + html-to-markdown snyk-test.html -o snyk + cat snyk/snyk-test.html.md >> $GITHUB_STEP_SUMMARY + fi + + - name: Publish Snyk Code Results + if: ${{ inputs.enable-snyk-scan && !cancelled() && !failure() }} + run: | + if [[ -f "snyk-code.json" && -n "$(cat snyk-code.json | tr -d '[:space:]')" ]]; then + snyk-to-html -i snyk-code.json -o snyk-code.html --summary + html-to-markdown snyk-code.html -o snyk + cat snyk/snyk-code.html.md >> $GITHUB_STEP_SUMMARY + fi + + - name: Check Snyk Files + if: ${{ always() }} + run: | + echo "::group::Snyk File List" + ls -lah snyk* || true + echo "::endgroup::" + echo "::group::Snyk Test Contents" + cat snyk-test.json || true + echo "::endgroup::" + echo "::group::Snyk Code Contents" + cat snyk-code.json || true + echo "::endgroup::" + + - name: Publish Snyk Reports + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + if: ${{ inputs.enable-snyk-scan && !cancelled() && !failure() }} + with: + name: Snyk Reports + path: | + snyk-*.html + snyk-*.json diff --git a/.github/workflows/zxc-compile-code.yaml b/.github/workflows/zxc-compile-code.yaml new file mode 100644 index 00000000..9d4d9ea2 --- /dev/null +++ b/.github/workflows/zxc-compile-code.yaml @@ -0,0 +1,127 @@ +## +# Copyright (C) 2023-2024 Hedera Hashgraph, LLC +# +# 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. +## + +name: 'ZXC: Compile Code' +# The purpose of this reusable workflow is to compile the code and run the unit tests on every PR and commit. +# This reusable component is called by the following workflows: +# - .github/workflows/flow-pull-request-checks.yaml +# - .github/workflows/flow-build-application.yaml + +on: + workflow_call: + inputs: + enable-unit-tests: + description: 'Unit Testing Enabled' + type: boolean + required: false + default: false + enable-code-style-check: + description: 'Code Style Check Enabled' + type: boolean + required: false + default: false + enable-e2e-tests: + description: 'E2E Testing Enabled' + type: boolean + required: false + default: false + node-version: + description: 'NodeJS Version:' + type: string + required: false + default: '20' + custom-job-label: + description: 'Custom Job Label:' + type: string + required: false + default: 'Compiles' + +defaults: + run: + shell: bash + +permissions: + id-token: write + contents: read + actions: read + pull-requests: write + checks: write + statuses: write + +jobs: + compile: + name: ${{ inputs.custom-job-label || 'Compiles' }} + runs-on: [self-hosted, Linux, medium, ephemeral] + steps: + - name: Checkout Code + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Setup Node + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: ${{ inputs.node-version }} + cache: npm + + - name: Install Dependencies + id: npm-deps + run: npm ci + + - name: Check Code Style + if: ${{ inputs.enable-code-style-check && !cancelled() && !failure() }} + run: npm run check + + - name: Run Unit Tests + if: ${{ inputs.enable-unit-tests && !cancelled() && !failure() }} + run: npm run unit-test + + - name: Publish Unit Test Report + uses: EnricoMi/publish-unit-test-result-action@f355d34d53ad4e7f506f699478db2dd71da9de5f # v2.15.1 + if: ${{ inputs.enable-unit-tests && steps.npm-deps.conclusion == 'success' && !cancelled() }} + with: + check_name: 'Unit Test Results' + files: 'junit.xml' + + - name: Publish Unit Test Coverage Report + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + if: ${{ inputs.enable-unit-tests && !cancelled() }} + with: + name: Unit Test Coverage Report + path: 'coverage/unit' + + - name: Run E2E Tests + if: ${{ inputs.enable-e2e-tests && !cancelled() && !failure() }} + run: npm run e2e-test + + - name: Publish E2E Test Report + uses: EnricoMi/publish-unit-test-result-action@f355d34d53ad4e7f506f699478db2dd71da9de5f # v2.15.1 + if: ${{ inputs.enable-e2e-tests && steps.npm-deps.conclusion == 'success' && !cancelled() }} + with: + check_name: 'E2E Test Results' + files: 'junit-e2e.xml' + + - name: Publish E2E Coverage Report + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + if: ${{ inputs.enable-e2e-tests && !cancelled() }} + with: + name: E2E Coverage Report + path: 'coverage/e2e' + + - name: Publish Test Reports + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + if: ${{ inputs.enable-unit-tests && steps.npm-deps.conclusion == 'success' && !cancelled() }} + with: + name: Test Reports + path: 'junit*.xml'