diff --git a/.commitlintrc.json b/.commitlintrc.json new file mode 100644 index 00000000..c30e5a97 --- /dev/null +++ b/.commitlintrc.json @@ -0,0 +1,3 @@ +{ + "extends": ["@commitlint/config-conventional"] +} diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml new file mode 100644 index 00000000..7e4c1a5e --- /dev/null +++ b/.github/workflows/commitlint.yml @@ -0,0 +1,25 @@ +name: Lint Commits + +on: + pull_request: + +jobs: + commitlint: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Setup Node.js + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + with: + node-version: '24' + + - name: Install dependencies + run: npm install + + - name: Validate commit messages + run: npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml new file mode 100644 index 00000000..351596af --- /dev/null +++ b/.github/workflows/prepare-release.yml @@ -0,0 +1,71 @@ +name: Prepare Release + +on: + push: + branches: + - master + +concurrency: + group: prepare-release + cancel-in-progress: true + +permissions: + contents: write + pull-requests: write + +jobs: + prepare: + runs-on: ubuntu-latest + if: "!startsWith(github.event.head_commit.message, 'chore(release):')" + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Setup Node.js + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + with: + node-version: '24' + + - name: Install dependencies + run: npm install + + - name: Detect Next Version + id: version + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + NEXT_VERSION=$(npx semantic-release --dry-run --plugins @semantic-release/commit-analyzer | tee /dev/stderr | awk '/The next release version is/{print $NF}') + echo "next=$NEXT_VERSION" >> $GITHUB_OUTPUT + + - name: Update package.json + if: steps.version.outputs.next != '' + run: npm version "$NEXT_VERSION" --no-git-tag-version + env: + NEXT_VERSION: ${{ steps.version.outputs.next }} + + - name: Update CHANGELOG.md + if: steps.version.outputs.next != '' + run: npx conventional-changelog-cli -p angular -i CHANGELOG.md -s + + - name: Create Pull Request + if: steps.version.outputs.next != '' + uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "chore(release): ${{ steps.version.outputs.next }}" + branch: "release/v${{ steps.version.outputs.next }}" + delete-branch: true + title: "chore(release): ${{ steps.version.outputs.next }}" + body: | + This PR prepares the release of version ${{ steps.version.outputs.next }}. + + **Changes:** + - Updated version in `package.json` to ${{ steps.version.outputs.next }} + - Updated `CHANGELOG.md` with release notes + + **Next Steps:** + Review and merge this PR to trigger the publish workflow. + labels: release diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..b4a5c6a6 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,63 @@ +name: Release + +on: + push: + branches: + - master + +permissions: + contents: write + issues: write + pull-requests: write + id-token: write + +jobs: + release: + runs-on: ubuntu-latest + if: startsWith(github.event.head_commit.message, 'chore(release):') + + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Setup Node.js + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + with: + node-version: '24' + + - name: Install dependencies + run: npm install + + - name: Set up Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + with: + python-version: "3.10" + + - name: Install Python dependencies + shell: bash + run: pip install boto3>=1.34.159 requests>=2.32.3 rl-deploy>=2.2.3.0 pip-system-certs>=4.0 + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6.0.0 + with: + role-to-assume: ${{ secrets.PRODSEC_TOOLS_ARN }} + aws-region: us-east-1 + mask-aws-account-id: true + + - name: Install rl-wrapper + env: + WRAPPER_INDEX_URL: "https://${{ secrets.PRODSEC_TOOLS_USER }}:${{ secrets.PRODSEC_TOOLS_TOKEN }}@a0us.jfrog.io/artifactory/api/pypi/python-local/simple" + run: pip install "rl-wrapper>=1.0.0" --index-url $WRAPPER_INDEX_URL + + - name: Release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_CONFIG_PROVENANCE: true + RLSECURE_LICENSE: ${{ secrets.RLSECURE_LICENSE }} + RLSECURE_SITE_KEY: ${{ secrets.RLSECURE_SITE_KEY }} + SIGNAL_HANDLER_TOKEN: ${{ secrets.SIGNAL_HANDLER_TOKEN }} + PYTHONUNBUFFERED: 1 + run: npx semantic-release diff --git a/.github/workflows/sca-scan.yml b/.github/workflows/sca-scan.yml new file mode 100644 index 00000000..4a61d879 --- /dev/null +++ b/.github/workflows/sca-scan.yml @@ -0,0 +1,10 @@ +name: Snyk Scan + +on: + push: + branches: ["master"] + +jobs: + snyk-cli: + uses: auth0/devsecops-tooling/.github/workflows/sca-scan.yml@5246a8b59100e3eea284ce4f2e2a51b51e237380 + secrets: inherit diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml deleted file mode 100644 index 1ba433de..00000000 --- a/.github/workflows/semgrep.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Semgrep - -on: - pull_request_target: {} - push: - branches: ["master", "main"] -jobs: - semgrep: - name: Scan - runs-on: ubuntu-latest - container: - image: returntocorp/semgrep - if: (github.actor != 'dependabot[bot]' && github.actor != 'snyk-bot') - steps: - - uses: actions/checkout@v3 - - run: semgrep ci - env: - SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bd1167bf..5d10d6a2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,10 +1,11 @@ name: Test on: - push: - branches: [master] pull_request: - branches: [master] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true permissions: contents: read @@ -14,16 +15,19 @@ jobs: strategy: fail-fast: false matrix: - node: [14, 16, 18, 20, 22, 24] + node: [16, 18, 20, 22, 24] name: Test (Node ${{ matrix.node }}) runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - name: Setup Node - uses: actions/setup-node@v6 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: ${{ matrix.node }} diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100755 index 00000000..0398b7a8 --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1 @@ +npx --no -- commitlint --edit ${1} diff --git a/.releaserc.json b/.releaserc.json new file mode 100644 index 00000000..01d9e2e7 --- /dev/null +++ b/.releaserc.json @@ -0,0 +1,24 @@ +{ + "branches": [ + "master" + ], + "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + [ + "@semantic-release/npm", + { + "npmPublish": true, + "pkgRoot": "." + } + ], + [ + "@semantic-release/exec", + { + "verifyReleaseCmd": "ARTIFACT=\"$(pwd)/$(npm pack --ignore-scripts | tail -1)\" && rl-wrapper --artifact \"$ARTIFACT\" --name jsonwebtoken --version ${nextRelease.version} --repository $GITHUB_REPOSITORY --commit $GITHUB_SHA --build-env github_actions --suppress-output", + "prepareCmd": "git diff --exit-code" + } + ], + "@semantic-release/github" + ] +} diff --git a/package.json b/package.json index eab30c0a..d85f183a 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "scripts": { "lint": "eslint .", "coverage": "nyc mocha --use_strict", - "test": "mocha" + "test": "mocha", + "prepare": "husky" }, "repository": { "type": "git", @@ -48,13 +49,18 @@ "semver": "^7.5.4" }, "devDependencies": { + "@commitlint/cli": "^20.3.1", + "@commitlint/config-conventional": "^20.3.1", + "@semantic-release/exec": "^7.0.3", "atob": "^2.1.2", "chai": "^4.1.2", "conventional-changelog": "~1.1.0", "eslint": "^4.19.1", + "husky": "^9.1.7", "mocha": "^5.2.0", "nsp": "^2.6.2", "nyc": "^11.9.0", + "semantic-release": "^25.0.2", "sinon": "^6.0.0" }, "engines": {