diff --git a/.github/workflows/codacy.yml b/.github/workflows/codacy.yml new file mode 100644 index 0000000..500f7d3 --- /dev/null +++ b/.github/workflows/codacy.yml @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: Apache-2.0 + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +# This workflow checks out code, performs a Codacy security scan +# and integrates the results with the +# GitHub Advanced Security code scanning feature. For more information on +# the Codacy security scan action usage and parameters, see +# https://github.com/codacy/codacy-analysis-cli-action. +# For more information on Codacy Analysis CLI in general, see +# https://github.com/codacy/codacy-analysis-cli. + +name: Codacy Security Scan + +on: + push: + branches: [ "dev", "main" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "dev", "main" ] + schedule: + - cron: '17 0 * * 4' + +permissions: + contents: read + +jobs: + codacy-security-scan: + permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results + actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status + name: Codacy Security Scan + runs-on: ubuntu-latest + steps: + # Checkout the repository to the GitHub Actions runner + - name: Checkout code + uses: actions/checkout@v4 + + # Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis + - name: Run Codacy Analysis CLI + uses: codacy/codacy-analysis-cli-action@3ff8e64eb4b714c4bee91b7b4eea31c6fc2c4f93 + with: + # Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository + # You can also omit the token and run the tools that support default configurations + project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} + verbose: true + output: results.sarif + format: sarif + # Adjust severity of non-security issues + gh-code-scanning-compat: true + # Force 0 exit code to allow SARIF file generation + # This will handover control about PR rejection to the GitHub side + max-allowed-issues: 2147483647 + + # Upload the SARIF file generated in the previous step + - name: Upload SARIF results file + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: results.sarif diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..88abae3 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,78 @@ +# SPDX-License-Identifier: Apache-2.0 + +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ "dev", "main" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "dev", "main" ] + schedule: + - cron: '34 0 * * 4' + +jobs: + analyze: + name: Analyze + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'javascript' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Use only 'java' to analyze code written in Java, Kotlin or both + # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v3 + + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/commit-message.yaml b/.github/workflows/commit-message.yaml new file mode 100644 index 0000000..70484e6 --- /dev/null +++ b/.github/workflows/commit-message.yaml @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Please do not attempt to edit this flow without the direct consent from the DevOps team. This file is managed centrally. +# Contact @moabu +name: 'Commit Message Check' +on: + pull_request: + types: + - opened + - edited + - reopened + - synchronize + push: + branches: [ "dev", "main" ] + +jobs: + check-commit-message: + name: Check Commit Message + runs-on: ubuntu-latest + + steps: + - name: Checkout Project + uses: actions/checkout@v4 + with: + # We need to fetch with a depth of 2 for pull_request so we can do HEAD^2 + fetch-depth: 2 + + - uses: actions/setup-node@v4.0.0 + with: + node-version: 14 + + - run: | + npm install --save-dev @commitlint/{config-conventional,cli} + echo "module.exports = {extends: ['@commitlint/config-conventional']};" > commitlint.config.js + + # If this workflow was triggered by a push then resolve the commit message from HEAD + - name: "[Push] Check Commit Standard" + if: github.event_name == 'push' || github.event_name == 'pull_request_target' + id: push_get_commit_message + run: | + git log --format=%B -n 1 HEAD | npx commitlint |& tee -a output.txt + echo "::set-output name=errormsg::$(tr -d "\n\r" < output.txt)" + git log --format=%B -n 1 HEAD | npx commitlint + continue-on-error: true + + # If this workflow was triggered by a pull request (open or synchronize!) then resolve the commit message from HEAD^2 + - name: "[Pull Request] Check Commit Standard" + if: github.event_name == 'pull_request' + id: pr_get_commit_message + run: | + git log --format=%B -n 1 HEAD^2 | npx commitlint |& tee -a output.txt + echo "::set-output name=errormsg::$(tr -d "\n\r" < output.txt)" + git log --format=%B -n 1 HEAD^2 | npx commitlint + continue-on-error: true + + - name: "[Push] Report Commit Standard Status" + if: steps.push_get_commit_message.outcome != 'success' && github.event_name == 'push' + run: | + curl -X POST -H 'Content-Type: application/json' --data '{"alias":"Mo-Auto","emoji":":robot:","text":":x: :cry: I am reporting a bad [commit](https://github.com/${{github.repository}}/commit/${{github.sha}}) by :thinking_face: @${{github.actor}} :x:","attachments":[{"title":"GitHub user behavior reporter","title_link":"https://www.conventionalcommits.org","text":"We are not too happy with your last [commit](https://github.com/${{github.repository}}/commit/${{github.sha}}). Here is why : ${{ steps.push_get_commit_message.outputs.errormsg }}","color":"#764FA5"}]}' ${{ secrets.GITHUBUSERBEHAVIORSLACKREPORTER }} + exit 1 + + - name: "[Pull Request] Report Commit Standard Status" + if: steps.pr_get_commit_message.outcome != 'success' && github.event_name == 'pull_request' + run: | + curl -X POST -H 'Content-Type: application/json' --data '{"alias":"Mo-Auto","emoji":":robot:","text":":x: :cry: I am reporting a bad [commit](https://github.com/${{github.repository}}/tree/$GITHUB_HEAD_REF) by :thinking_face: @${{github.actor}} :x:","attachments":[{"title":"GitHub user behavior reporter","title_link":"https://www.conventionalcommits.org","text":"We are not too happy with your last commit merging into https://github.com/${{github.repository}}/tree/${{github.base_ref}}. Here is why : ${{ steps.pr_get_commit_message.outputs.errormsg }}","color":"#764FA5"}]}' ${{ secrets.GITHUBUSERBEHAVIORSLACKREPORTER }} + exit 1 diff --git a/.github/workflows/conventional-commits.yml b/.github/workflows/conventional-commits.yml new file mode 100644 index 0000000..68efbd2 --- /dev/null +++ b/.github/workflows/conventional-commits.yml @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: Apache-2.0 + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +# This GitHub Actions workflow validates the title of pull requests (PRs) to ensure they follow conventional commit standards. + +name: PR Conventional Commit Validation + +on: + # Trigger this workflow on specific events related to pull requests + pull_request: + types: [opened, synchronize, reopened, edited] + +jobs: + validate-pr-title: + runs-on: ubuntu-latest # Use the latest Ubuntu runner for the job + steps: + - name: Checkout code + uses: actions/checkout@v4 # Checkout the repository code using the actions/checkout action + + - name: PR Conventional Commit Validation + uses: ytanikin/PRConventionalCommits@1.1.0 # Use the PRConventionalCommits action to validate PR titles + with: + # Define the task types that are valid for conventional commits + task_types: '["build","ci","docs","feat","fix","perf","refactor","style","test","feat!"]' + # Map the conventional commit types to corresponding GitHub labels + custom_labels: '{"build": "build", "ci": "CI/CD", "docs": "documentation", "feat": "enhancement", "fix": "bug", "perf": "performance", "refactor": "refactor", "style": "style", "test": "test", "feat!": "enhancement breaking change"}' + # Use a personal access token (GITHUB_TOKEN) stored in GitHub secrets for authentication + token: ${{ secrets.GITHUB_TOKEN }} + add_label: 'true' diff --git a/.github/workflows/dco-check.yaml b/.github/workflows/dco-check.yaml new file mode 100644 index 0000000..a9c9b5e --- /dev/null +++ b/.github/workflows/dco-check.yaml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: Apache-2.0 + +# This GitHub Actions workflow checks that all commits in a pull request (PR) have a "Signed-off-by" line to ensure Developer Certificate of Origin (DCO) compliance. + +name: DCO + +# Trigger the workflow on pull request events +on: [pull_request] + +jobs: + dco: + # Define the runner environment + runs-on: ubuntu-latest + + steps: + # Step to check out the repository + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Fetch all history for all branches to ensure complete commit history is available + + # Step to check each commit in the pull request for a Signed-off-by line + - name: Check for DCO Sign-off + run: | + # Get the base branch and head branch of the pull request + base_branch=${{ github.event.pull_request.base.ref }} + head_branch=${{ github.event.pull_request.head.ref }} + + # Get the list of commit hashes between the head branch and base branch + commits=$(git log --pretty=format:%H origin/${head_branch}..origin/${base_branch}) + non_compliant_commits="" + + # Loop through each commit and check for the Signed-off-by line + for commit in $commits; do + # Check if the commit message contains the Signed-off-by line + if ! git show --quiet --format=%B $commit | grep -q "^Signed-off-by: "; then + # If not, add the commit hash to the list of non-compliant commits + non_compliant_commits="$non_compliant_commits $commit" + fi + done + + # If there are any non-compliant commits, output their hashes and fail the job + if [ -n "$non_compliant_commits" ]; then + echo "The following commits do not have a Signed-off-by line:" + for commit in $non_compliant_commits; do + echo "- $commit" + done + exit 1 + fi + shell: bash diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 0000000..b8a269e --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Dependency Review Action +# +# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging. +# +# Source repository: https://github.com/actions/dependency-review-action +# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement +name: 'Dependency Review' +on: [pull_request] + +permissions: + contents: read + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: 'Checkout Repository' + uses: actions/checkout@v4 + - name: 'Dependency Review' + uses: actions/dependency-review-action@v4 diff --git a/.github/workflows/dockerfile-linter.yaml b/.github/workflows/dockerfile-linter.yaml new file mode 100644 index 0000000..89f8cb4 --- /dev/null +++ b/.github/workflows/dockerfile-linter.yaml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: Apache-2.0 + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. +# hadoint is a Dockerfile linter written in Haskell +# that helps you build best practice Docker images. +# More details at https://github.com/hadolint/hadolint + +name: Hadolint + +on: + push: + branches: [ "dev", "main" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "dev" ] + schedule: + - cron: '17 13 * * 0' + +permissions: + contents: read + +jobs: + hadolint: + name: Run hadolint scanning + runs-on: ubuntu-latest + permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results + actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Run hadolint + uses: hadolint/hadolint-action@f988afea3da57ee48710a9795b6bb677cc901183 + with: + dockerfile: ./Dockerfile + format: sarif + output-file: hadolint-results.sarif + no-fail: true + + - name: Upload analysis results to GitHub + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: hadolint-results.sarif + wait-for-processing: true \ No newline at end of file diff --git a/.github/workflows/gpg-verify.yml b/.github/workflows/gpg-verify.yml new file mode 100644 index 0000000..5bc2b33 --- /dev/null +++ b/.github/workflows/gpg-verify.yml @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: Apache-2.0 + +# This GitHub Actions workflow checks that all commits in a pull request (PR) have been verified with GPG signatures. + +name: GPG Verify + +on: [pull_request] # Trigger this workflow on pull request events + +jobs: + gpg-verify: + runs-on: ubuntu-latest # Use the latest Ubuntu runner for the job + steps: + - uses: actions/checkout@v4 # Checkout the repository code using the actions/checkout action + with: + fetch-depth: 0 # Fetch all history for all branches to ensure we have the full commit history + + - name: Check GPG verification status # Step to check each commit for GPG signature verification + run: | + # Get the list of commits in the pull request + commits=$(git log --pretty=format:%H origin/${{ github.event.pull_request.head.ref }}..origin/${{ github.event.pull_request.base.ref }}) + + # Check the GPG verification status of each commit + for commit in $commits; do + status=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + https://api.github.com/repos/${{ github.repository }}/commits/$commit/check-runs \ + | jq -r '.check_runs[] | select(.name == "GPG verify") | .conclusion') + + # If the GPG verification status is not successful, list the commit and exit with a non-zero status + if [[ "$status" != "success" ]]; then + echo "GPG signature verification failed for commit $commit." + exit 1 + fi + done diff --git a/.github/workflows/linting.yaml b/.github/workflows/linting.yaml new file mode 100644 index 0000000..87bbd40 --- /dev/null +++ b/.github/workflows/linting.yaml @@ -0,0 +1,52 @@ +# SPDX-License-Identifier: Apache-2.0 + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. +# ESLint is a tool for identifying and reporting on patterns +# found in ECMAScript/JavaScript code. +# More details at https://github.com/eslint/eslint +# and https://eslint.org + +name: ESLint + +on: + push: + branches: [ "dev", "main" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "dev", "main" ] + schedule: + - cron: '33 13 * * 1' + +jobs: + eslint: + name: Run eslint scanning + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write + actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install ESLint + run: | + npm install eslint@8.10.0 + npm install @microsoft/eslint-formatter-sarif@2.1.7 + + - name: Run ESLint + run: npx eslint . + --config .eslintrc.js + --ext .js,.jsx,.ts,.tsx + --format @microsoft/eslint-formatter-sarif + --output-file eslint-results.sarif + continue-on-error: true + + - name: Upload analysis results to GitHub + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: eslint-results.sarif + wait-for-processing: true \ No newline at end of file diff --git a/.github/workflows/milestone.yaml b/.github/workflows/milestone.yaml new file mode 100644 index 0000000..dd67ba3 --- /dev/null +++ b/.github/workflows/milestone.yaml @@ -0,0 +1,52 @@ +# SPDX-License-Identifier: Apache-2.0 + +name: Milestone Workflow + +on: + workflow_dispatch: + inputs: + milestoneId: + description: 'Milestone ID' + required: true + default: '1' + +jobs: + close_milestone: + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v2 + + - name: Setup Node.js (.npmrc) + uses: actions/setup-node@v3 + with: + node-version: 16.x + registry-url: https://npm.pkg.github.com/ + # Defaults to the user or organization that owns the workflow file + scope: '@frmscoe' + + - name: Install dependencies + run: npm ci + env: + GH_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + + - name: Close Milestone + run: | + ACCESS_TOKEN="${{ secrets.GITHUB_TOKEN }}" + MILESTONE_NUMBER=${{ github.event.inputs.milestoneId }} + API_URL="https://api.github.com" + + curl -X PATCH \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Authorization: Bearer $ACCESS_TOKEN" \ + -d '{"state": "closed"}' \ + $API_URL/repos/${{ github.repository }}/milestones/$MILESTONE_NUMBER + + - name: Trigger Release Workflow + uses: peter-evans/repository-dispatch@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + repository: ${{ github.repository }} + event-type: release + client-payload: '{"milestone_number": "${{ github.event.inputs.milestoneId }}"}' \ No newline at end of file diff --git a/.github/workflows/njsscan.yml b/.github/workflows/njsscan.yml new file mode 100644 index 0000000..255c0f7 --- /dev/null +++ b/.github/workflows/njsscan.yml @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: Apache-2.0 + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +# This workflow integrates njsscan with GitHub's Code Scanning feature +# nodejsscan is a static security code scanner that finds insecure code patterns in your Node.js applications + +name: njsscan sarif + +on: + push: + branches: [ "dev", "main" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "dev", "main" ] + schedule: + - cron: '17 17 * * 1' + +permissions: + contents: read + +jobs: + njsscan: + permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results + actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status + runs-on: ubuntu-latest + name: njsscan code scanning + steps: + - name: Checkout the code + uses: actions/checkout@v4 + - name: nodejsscan scan + id: njsscan + uses: ajinabraham/njsscan-action@d58d8b2f26322cd35a9efb8003baac517f226d81 + with: + args: '. --sarif --output results.sarif || true' + - name: Upload njsscan report + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: results.sarif diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml new file mode 100644 index 0000000..10aa456 --- /dev/null +++ b/.github/workflows/node.js.yml @@ -0,0 +1,83 @@ +# SPDX-License-Identifier: Apache-2.0 + +# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs + +name: Node.js CI + +env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_SCOPE: "@frmscoe" + NPM_REGISTRY: "https://npm.pkg.github.com/" + NODE_ENV: 'test' + STARTUP_TYPE: 'nats' + +on: + push: + branches: [ "dev", "main" ] + pull_request: + branches: [ "dev", "main" ] +jobs: + build: + runs-on: ubuntu-latest + name: run build + strategy: + matrix: + node-version: [16, 20] + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + registry-url: ${{ env.NPM_REGISTRY }} + scope: ${{ env.NPM_SCOPE }} + - name: Install dependencies + run: npm ci + - name: Run build + run: npm run build + + lint: + runs-on: ubuntu-latest + name: check style + strategy: + matrix: + node-version: [20] + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + registry-url: ${{ env.NPM_REGISTRY }} + scope: ${{ env.NPM_SCOPE }} + - name: Install dependencies + run: npm ci + - name: Check linting + run: npm run lint + - name: Check formatting + run: npm run lint:prettier + + test: + runs-on: ubuntu-latest + name: check tests + strategy: + matrix: + node-version: [20] + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + registry-url: ${{ env.NPM_REGISTRY }} + scope: ${{ env.NPM_SCOPE }} + - name: Install dependencies + run: npm ci + - name: Run tests + run: npm test diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..aa51719 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,207 @@ +# SPDX-License-Identifier: Apache-2.0 + +name: Release Workflow + +on: + repository_dispatch: + types: [release] + properties: + milestone_number: + type: string +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v2 + with: + ref: main + fetch-depth: 0 # Fetch all tags + + # Fetch merged pull request and determine release labels + - uses: actions-ecosystem/action-get-merged-pull-request@v1 + id: get-merged-pull-request + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions-ecosystem/action-release-label@v1 + id: release-label + if: ${{ steps.get-merged-pull-request.outputs.title != null }} + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + #labels: ${{ steps.get-merged-pull-request.outputs.labels }} + + # Get the latest tag in the repositorys + - uses: actions-ecosystem/action-get-latest-tag@v1 + id: get-latest-tag + if: ${{ steps.release-label.outputs.level != null }} + with: + semver_only: true + + - name: Setup Node.js (.npmrc) + uses: actions/setup-node@v3 + with: + node-version: 16.x + registry-url: https://npm.pkg.github.com/ + # Defaults to the user or organization that owns the workflow file + scope: '@frmscoe' + + - name: Install dependencies + run: npm ci + env: + GH_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + + - name: Run Tests + run: npm test + env: + STARTUP_TYPE: 'nats' + + # Determine the release type (major, minor, patch) based on commit messages + - name: Determine Release Type + id: determine_release + run: | + export PREV_VERSION=$(git describe --abbrev=0 --tags) + echo "Previous Version: $PREV_VERSION" + + export COMMIT_MESSAGES=$(git log $PREV_VERSION^..HEAD --format=%B) + echo "Commit Messages: $COMMIT_MESSAGES" + + # Determine release type based on commit messages and labels + RELEASE_TYPE="patch" # Default to patch + + if echo "$COMMIT_MESSAGES" | grep -q -e "BREAKING CHANGE:"; then + RELEASE_TYPE="major" + elif echo "$COMMIT_MESSAGES" | grep -q -e "feat:"; then + RELEASE_TYPE="minor" + elif echo "$COMMIT_MESSAGES" | grep -q -e "feat:" && (echo "$COMMIT_MESSAGES" | grep -q -e "fix:" || echo "$COMMIT_MESSAGES" | grep -q -e "enhancement:" || echo "$COMMIT_MESSAGES" | grep -q -e "docs:" || echo "$COMMIT_MESSAGES" | grep -q -e "refactor:" || echo "$COMMIT_MESSAGES" | grep -q -e "chore:"); then + RELEASE_TYPE="minor" + elif echo "$COMMIT_MESSAGES" | grep -q -e "fix:" -e "enhancement:" -e "docs:" -e "refactor:" -e "chore:"; then + RELEASE_TYPE="patch" + fi + + echo "Release Type: $RELEASE_TYPE" + echo "::set-output name=release_type::$RELEASE_TYPE" + + # Bump the version based on the determined release type + - name: Bump Version + id: bump_version + run: | + export PREV_VERSION=$(git describe --abbrev=0 --tags) + echo "Previous Version: $PREV_VERSION" + + export RELEASE_TYPE=${{ steps.determine_release.outputs.release_type }} + echo "Release Type: $RELEASE_TYPE" + + export VERSION_PARTS=($(echo $PREV_VERSION | tr '.' '\n')) + MAJOR=${VERSION_PARTS[0]} + MINOR=${VERSION_PARTS[1]} + PATCH=${VERSION_PARTS[2]} + + if [[ $RELEASE_TYPE == "major" ]]; then + MAJOR=$((MAJOR + 1)) + MINOR=0 + PATCH=0 + elif [[ $RELEASE_TYPE == "minor" ]]; then + MINOR=$((MINOR + 1)) + PATCH=0 + else + PATCH=$((PATCH + 1)) + fi + + NEW_VERSION="$MAJOR.$MINOR.$PATCH" + echo "New Version: $NEW_VERSION" + echo "::set-output name=new_version::$NEW_VERSION" + + # Get the milestone details + - name: Get Milestone Details + id: get_milestone + run: | + # Retrieve the milestone ID from the workflow input + MILESTONE_ID=${{ github.event.client_payload.milestone_number }} + MILESTONE_RESPONSE=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" "https://api.github.com/repos/${{ github.repository }}/milestones/${MILESTONE_ID}") + MILESTONE_TITLE=$(echo "$MILESTONE_RESPONSE" | jq -r '.title') + MILESTONE_DESCRIPTION=$(echo "$MILESTONE_RESPONSE" | jq -r '.description') + MILESTONE_DATE=$(echo "$MILESTONE_RESPONSE" | jq -r '.due_on') + echo "::set-output name=milestone_title::$MILESTONE_TITLE" + echo "::set-output name=milestone_description::$MILESTONE_DESCRIPTION" + echo "::set-output name=milestone_date::$MILESTONE_DATE" + + # Generate the changelog based on commit messages and labels + - name: Generate Changelog + id: generate_changelog + run: | + # Generate Changelog Script + # Constants + CHANGELOG_FILE="/home/runner/work/changelog.txt" + LABEL_BUG="fix:" + LABEL_FEATURE="feat:" + LABEL_ENHANCEMENT="enhancement:" + LABEL_DOCS="docs:" + LABEL_REFACTOR="refactor:" + LABEL_CHORE="chore:" + LABEL_BREAKING_CHANGE="BREAKING CHANGE:" + # Get the last release tag + LAST_RELEASE_TAG=$(git describe --abbrev=0 --tags) + # Get the milestone details from the output of the previous step + MILESTONE_TITLE="${{ steps.get_milestone.outputs.milestone_title }}" + MILESTONE_DESCRIPTION="${{ steps.get_milestone.outputs.milestone_description }}" + MILESTONE_DATE="${{ steps.get_milestone.outputs.milestone_date }}" + # Append the milestone details to the changelog file + echo "## Milestone: $MILESTONE_TITLE" >> "$CHANGELOG_FILE" + echo "Date: $MILESTONE_DATE" >> "$CHANGELOG_FILE" + echo "Description: $MILESTONE_DESCRIPTION" >> "$CHANGELOG_FILE" + echo "" >> "$CHANGELOG_FILE" + # Function to append section to the changelog file + append_section() { + local section_title="$1" + local section_label="$2" + local section_icon="$3" + # Get the commit messages with the specified label between the last release and the current release + local commit_messages=$(git log --pretty=format:"- %s (Linked Issues: %C(yellow)%H%Creset)" "$LAST_RELEASE_TAG..HEAD" --grep="$section_label" --no-merges --decorate --decorate-refs=refs/issues) + # If there are commit messages, append the section to the changelog file + if [ -n "$commit_messages" ]; then + echo "### $section_icon $section_title" >> "$CHANGELOG_FILE" + echo "" >> "$CHANGELOG_FILE" + echo "$commit_messages" >> "$CHANGELOG_FILE" + echo "" >> "$CHANGELOG_FILE" + fi + } + # Append sections to the changelog file based on labels + append_section "Bug Fixes" "$LABEL_BUG" "🐞" + append_section "New Features" "$LABEL_FEATURE" "⭐ī¸" + append_section "Enhancements" "$LABEL_ENHANCEMENT" "✨" + append_section "Documentation" "$LABEL_DOCS" "📚" + append_section "Refactorings" "$LABEL_REFACTOR" "🔨" + append_section "Chores" "$LABEL_CHORE" "⚙ī¸" + append_section "Breaking Changes" "$LABEL_BREAKING_CHANGE" "đŸ’Ĩ" + echo "::set-output name=changelog_file::$CHANGELOG_FILE" + + # Read changelog contents into a variable + - name: Read Changelog Contents + id: read_changelog + run: | + echo "::set-output name=changelog_contents::$(cat /home/runner/work/changelog.txt)" + + # Display changelog + - name: Display Changelog + run: cat /home/runner/work/changelog.txt + + # Attach changelog as an artifact + - name: Attach Changelog to Release + uses: actions/upload-artifact@v2 + with: + name: Changelog + path: /home/runner/work/changelog.txt + + # Create release while including the changelog + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ steps.bump_version.outputs.new_version }} + release_name: ${{ steps.bump_version.outputs.new_version }} + body_path: /home/runner/work/changelog.txt + draft: false + prerelease: false diff --git a/.github/workflows/scorecard.yaml b/.github/workflows/scorecard.yaml new file mode 100644 index 0000000..b21d884 --- /dev/null +++ b/.github/workflows/scorecard.yaml @@ -0,0 +1,75 @@ +# SPDX-License-Identifier: Apache-2.0 + +# This workflow uses actions that are not certified by GitHub. They are provided +# by a third-party and are governed by separate terms of service, privacy +# policy, and support documentation. + +name: Scorecard supply-chain security +on: + # For Branch-Protection check. Only the default branch is supported. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection + branch_protection_rule: + # To guarantee Maintained check is occasionally updated. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained + schedule: + - cron: '35 3 * * 3' + push: + branches: [ "dev", "main" ] + +# Declare default permissions as read only. +permissions: read-all + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + permissions: + # Needed to upload the results to code-scanning dashboard. + security-events: write + # Needed to publish results and get a badge (see publish_results below). + id-token: write + # Uncomment the permissions below if installing in a private repository. + # contents: read + # actions: read + + steps: + - name: "Checkout code" + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + persist-credentials: false + + - name: "Run analysis" + uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 + with: + results_file: results.sarif + results_format: sarif + # (Optional) "write" PAT token. Uncomment the `repo_token` line below if: + # - you want to enable the Branch-Protection check on a *public* repository, or + # - you are installing Scorecard on a *private* repository + # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action?tab=readme-ov-file#authentication-with-fine-grained-pat-optional. + # repo_token: ${{ secrets.SCORECARD_TOKEN }} + + # Public repositories: + # - Publish results to OpenSSF REST API for easy access by consumers + # - Allows the repository to include the Scorecard badge. + # - See https://github.com/ossf/scorecard-action#publishing-results. + # For private repositories: + # - `publish_results` will always be set to `false`, regardless + # of the value entered here. + publish_results: true + + # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF + # format to the repository Actions tab. + - name: "Upload artifact" + uses: actions/upload-artifact@97a0fba1372883ab732affbe8f94b823f91727db # v3.pre.node20 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + + # Upload the results to GitHub's code scanning dashboard (optional). + # Commenting out will disable upload of results to your repo's Code Scanning dashboard + - name: "Upload to code-scanning" + uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 + with: + sarif_file: results.sarif \ No newline at end of file diff --git a/.github/workflows/terraform-security.yaml b/.github/workflows/terraform-security.yaml new file mode 100644 index 0000000..ea0b88e --- /dev/null +++ b/.github/workflows/terraform-security.yaml @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: Apache-2.0 + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +name: tfsec + +on: + push: + branches: [ "dev", "main" ] + pull_request: + branches: [ "dev" ] + schedule: + - cron: '31 11 * * 1' + +jobs: + tfsec: + name: Run tfsec sarif report + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + steps: + - name: Clone repo + uses: actions/checkout@v4 + + - name: Run tfsec + uses: aquasecurity/tfsec-sarif-action@21ded20e8ca120cd9d3d6ab04ef746477542a608 + with: + sarif_file: tfsec.sarif + + - name: Upload SARIF file + uses: github/codeql-action/upload-sarif@v2 + with: + # Path to SARIF file relative to the root of the repository + sarif_file: tfsec.sarif