diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml new file mode 100644 index 00000000..5c457157 --- /dev/null +++ b/.github/actions/setup/action.yml @@ -0,0 +1,32 @@ +name: Build package +description: Build the SDK package + +inputs: + ruby: + description: The Ruby version to use + required: false + default: 3.2 + bundle-path: + description: The path to the bundle cache + required: false + default: vendor/bundle + bundler-cache: + description: Whether to use the bundler cache + required: false + default: true + +runs: + using: composite + + steps: + - name: Configure Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ inputs.ruby }} + bundler-cache: ${{ inputs.bundle-cache }} + + - name: Install dependencies + run: bundle check || bundle install + shell: bash + env: + BUNDLE_PATH: ${{ inputs.bundle-path }} diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 32f056f4..f2df3e4c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,10 +1,13 @@ version: 2 updates: - - - package-ecosystem: "bundler" - directory: "/" + - package-ecosystem: "bundler" + directory: "/" schedule: interval: "daily" ignore: - dependency-name: "*" update-types: ["version-update:semver-major"] + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'daily' diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000..be639066 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,53 @@ +name: CodeQL + +on: + merge_group: + pull_request: + types: + - opened + - synchronize + push: + branches: + - master + schedule: + - cron: "37 10 * * 2" + +permissions: + actions: read + contents: read + security-events: write + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} + +jobs: + analyze: + name: Check for Vulnerabilities + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + language: [ruby] + + steps: + - if: github.actor == 'dependabot[bot]' || github.event_name == 'merge_group' + run: exit 0 # Skip unnecessary test runs for dependabot and merge queues. Artifically flag as successful, as this is a required check for branch protection. + + - name: Checkout + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + queries: +security-and-quality + + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{ matrix.language }}" diff --git a/.github/workflows/matrix.json b/.github/workflows/matrix.json new file mode 100644 index 00000000..2e4e771c --- /dev/null +++ b/.github/workflows/matrix.json @@ -0,0 +1,7 @@ +{ + "include": [ + { "ruby": "3.0" }, + { "ruby": "3.1" }, + { "ruby": "3.2" } + ] +} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000..10ff092a --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,41 @@ +name: Publish Release + +on: + workflow_dispatch: + inputs: + branch: + description: The branch to release from. + required: true + default: master + +permissions: + contents: read + +jobs: + publish: + name: Publish to NPM + runs-on: ubuntu-latest + environment: release + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ github.event.inputs.branch }} + + - name: Configure Ruby + uses: ./.github/actions/setup + with: + ruby: 3.2 + + - name: Publish to RubyGems + run: | + mkdir -p $HOME/.gem + touch $HOME/.gem/credentials + chmod 0600 $HOME/.gem/credentials + printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials + gem build *.gemspec + gem push *.gem + env: + GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}" diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml index 326471a6..fc7d2eeb 100644 --- a/.github/workflows/semgrep.yml +++ b/.github/workflows/semgrep.yml @@ -1,28 +1,49 @@ name: Semgrep on: - pull_request: {} - + merge_group: + pull_request_target: + types: + - opened + - synchronize push: branches: - master - - main - schedule: - - cron: '0 * * * *' + - cron: '30 0 1,15 * *' + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} jobs: - semgrep: - name: Scan + authorize: + name: Authorize + environment: ${{ github.actor != 'dependabot[bot]' && github.event_name == 'pull_request_target' && github.event.pull_request.head.repo.full_name != github.repository && 'external' || 'internal' }} runs-on: ubuntu-latest + steps: + - run: true + + run: + needs: authorize # Require approval before running on forked pull requests + + name: Check for Vulnerabilities + runs-on: ubuntu-latest + container: image: returntocorp/semgrep - if: (github.repository_owner == 'auth0') - + steps: - - uses: actions/checkout@v3 + - if: github.actor == 'dependabot[bot]' || github.event_name == 'merge_group' + run: exit 0 # Skip unnecessary test runs for dependabot and merge queues. Artifically flag as successful, as this is a required check for branch protection. + + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha || github.ref }} - - if: github.event.pull_request.draft == false && github.actor != 'dependabot[bot]' - run: semgrep ci + - run: semgrep ci env: SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} diff --git a/.github/workflows/snyk.yml b/.github/workflows/snyk.yml new file mode 100644 index 00000000..4b27ea3d --- /dev/null +++ b/.github/workflows/snyk.yml @@ -0,0 +1,47 @@ +name: Snyk + +on: + merge_group: + workflow_dispatch: + pull_request_target: + types: + - opened + - synchronize + push: + branches: + - master + schedule: + - cron: '30 0 1,15 * *' + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} + +jobs: + authorize: + name: Authorize + environment: ${{ github.actor != 'dependabot[bot]' && github.event_name == 'pull_request_target' && github.event.pull_request.head.repo.full_name != github.repository && 'external' || 'internal' }} + runs-on: ubuntu-latest + steps: + - run: true + + check: + needs: authorize + + name: Check for Vulnerabilities + runs-on: ubuntu-latest + + steps: + - if: github.actor == 'dependabot[bot]' || github.event_name == 'merge_group' + run: exit 0 # Skip unnecessary test runs for dependabot and merge queues. Artifically flag as successful, as this is a required check for branch protection. + + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha || github.ref }} + + - uses: snyk/actions/php@b98d498629f1c368650224d6d212bf7dfa89e4bf # pin@0.4.0 + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..d007c25e --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,67 @@ +name: Build and Test + +on: + merge_group: + workflow_dispatch: + pull_request: + branches: + - master + push: + branches: + - master + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} + +env: + CACHE_KEY: "${{ github.ref }}-${{ github.run_id }}-${{ github.run_attempt }}" + +jobs: + configure: + name: Configure Build Matrix + runs-on: ubuntu-latest + + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha || github.ref }} + + - id: set-matrix + run: echo "matrix=$(jq -c . < ./.github/workflows/matrix.json)" >> $GITHUB_OUTPUT + + unit: + needs: configure + + name: Run Unit Tests + runs-on: ubuntu-latest + + strategy: + matrix: ${{ fromJson(needs.configure.outputs.matrix) }} + + env: + DOMAIN: example.auth0.dev + CLIENT_ID: example-client + CLIENT_SECRET: example-secret + MASTER_JWT: example-jwt + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Configure Ruby + uses: ./.github/actions/setup + with: + ruby: ${{ matrix.ruby }} + + - name: Run tests + run: bundle exec rake test + + - name: Upload coverage + uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # pin@3.1.4