diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 0000000..d00c1ec --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,51 @@ +name-template: 'v$RESOLVED_VERSION 🌈' +tag-template: 'v$RESOLVED_VERSION' +categories: + - title: '🚀 Features' + labels: + - 'feature' + - 'enhancement' + - title: '🐛 Bug Fixes' + labels: + - 'fix' + - 'bugfix' + - 'bug' + - 'hotfix' + - title: '🧰 Maintenance' + labels: + - 'chore' + - 'chore: major' + - 'chore: minor' + - 'chore: patch' + - 'refactor' + - 'restructure' + - 'cleanup' + - 'ci' + - 'perf' + - 'build' + - 'security' + - 'infrastructure' + - title: '📦 Dependencies' + labels: + - 'renovate' + - title: '📚 Documentation' + labels: + - 'docs' + - 'documentation' +change-template: '- $TITLE @$AUTHOR (#$NUMBER)' +change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks. +version-resolver: + major: + labels: + - 'release: major' + minor: + labels: + - 'release: minor' + patch: + labels: + - 'release: patch' +template: | + ## Changes + + $CHANGES + diff --git a/.github/release.yml b/.github/release.yml index 70148fa..a412ce0 100644 --- a/.github/release.yml +++ b/.github/release.yml @@ -16,6 +16,10 @@ changelog: - maintenance - refactor - chore + - chore:deps + - chore:devdeps + - chore:ci + - ci - title: "📝 Documentation" labels: diff --git a/.github/renovate.json5 b/.github/renovate.json5 index f53a2d5..d03879a 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -19,7 +19,7 @@ "assignees": ["Okabe-Junya"], - "labels": ["dependencies", "renovate", "bot"], + "labels": ["dependencies", "renovate", "bot", "release: none"], "dependencyDashboard": true, @@ -34,16 +34,15 @@ }, { "matchUpdateTypes": ["major"], - "addLabels": ["bump: major"] + "addLabels": ["chore: major"] }, { "matchUpdateTypes": ["minor"], - "addLabels": ["bump: minor"] + "addLabels": ["chore: minor"] }, { "matchUpdateTypes": ["patch"], - "addLabels": ["bump: patch"], - "automerge": true + "addLabels": ["chore: patch"] }, { "commitMessageTopic": "Node.js", diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml new file mode 100644 index 0000000..cef3b23 --- /dev/null +++ b/.github/workflows/audit.yml @@ -0,0 +1,29 @@ +name: audit +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + audit: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v2 + with: + node-version: 20 + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Audit dependencies + run: yarn audit --groups dependencies --level moderate + + - name: Audit devDependencies + run: yarn audit --groups devDependencies --level moderate diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..9854685 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,42 @@ +name: build and compare dist +on: + pull_request: + branches: + - main + push: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: checkout repo + uses: actions/checkout@v3 + + - name: setup node + uses: actions/setup-node@v3 + with: + node-version: '20' + + - name: install dependencies + run: yarn install --frozen-lockfile + + - name: rebuild + run: yarn build + + - name: compare dist + run: | + if [ "$(git diff --ignore-space-at-eol ./dist | wc -l)" -gt "0" ]; then + echo "dist is not up to date" + git diff + exit 1 + fi + id: diff + + - name: upload artifact + if: ${{ steps.diff.outputs.exit_code == '1' }} + uses: actions/upload-artifact@v3 + with: + name: dist + path: dist diff --git a/.github/workflows/label-bot.yml b/.github/workflows/label-bot.yml new file mode 100644 index 0000000..5a74983 --- /dev/null +++ b/.github/workflows/label-bot.yml @@ -0,0 +1,82 @@ +name: labeler bot + +on: + pull_request: + types: [opened, edited] + issue_comment: + types: [created, edited] + +jobs: + label: + runs-on: ubuntu-latest + steps: + - name: check-label + uses: actions/github-script@v3 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const labels = ["release: major", "release: minor", "release: patch", "release: none"]; + const issue = context.issue; + const issue_number = issue.number; + const owner = issue.owner; + const repo = issue.repo; + const { data: issue_data } = await github.issues.get({ + owner: owner, + repo: repo, + issue_number: issue_number + }); + const issue_labels = issue_data.labels.map(label => label.name); + const is_release_label = labels.some(label => issue_labels.includes(label)); + if (is_release_label) { + core.setOutput("is_release_label", "true"); + } else { + core.setOutput("is_release_label", "false"); + } + + - name: add-label + if: steps.check-label.outputs.is_release_label == 'false' + uses: actions/github-script@v3 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const issue = context.issue; + const issue_number = issue.number; + const owner = issue.owner; + const repo = issue.repo; + const comment = context.payload.comment.body; + if (comment.match(/\/release major/)) { + await github.issues.addLabels({ + owner: owner, + repo: repo, + issue_number: issue_number, + labels: ["release: major"] + }); + } else if (comment.match(/\/release minor/)) { + await github.issues.addLabels({ + owner: owner, + repo: repo, + issue_number: issue_number, + labels: ["release: minor"] + }); + } else if (comment.match(/\/release patch/)) { + await github.issues.addLabels({ + owner: owner, + repo: repo, + issue_number: issue_number, + labels: ["release: patch"] + }); + } else if (comment.match(/\/release none/)) { + await github.issues.addLabels({ + owner: owner, + repo: repo, + issue_number: issue_number, + labels: ["release: none"] + }); + } else { + await github.issues.createComment({ + owner: owner, + repo: repo, + issue_number: issue_number, + body: "Please add a label to this issue. \n\n- `/release major` \n- `/release minor` \n- `/release patch` \n- `/release none`" + }); + } diff --git a/.github/workflows/metrics.yml b/.github/workflows/metrics.yml index 04356fb..8b5996b 100644 --- a/.github/workflows/metrics.yml +++ b/.github/workflows/metrics.yml @@ -32,7 +32,7 @@ jobs: uses: github/issue-metrics@v2 env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SEARCH_QUERY: 'repo:Okabe-Junya/issue-validator is:issue is:pr created:${{ env.last_month }} -reason:"not planned"' + SEARCH_QUERY: 'repo:Okabe-Junya/issue-validator is:"issue pr" created:${{ env.last_month }} -reason:"not planned"' - name: Create issue uses: peter-evans/create-issue-from-file@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..6830ef3 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,22 @@ +name: Release Drafter + +on: + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + +jobs: + update_release_draft: + permissions: + contents: write + pull-requests: write + runs-on: ubuntu-latest + steps: + - name: release drafter + uses: release-drafter/release-drafter@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/dist/index.js b/dist/index.js index b9b4979..062763f 100644 --- a/dist/index.js +++ b/dist/index.js @@ -9686,7 +9686,7 @@ async function validateIssueTitleAndBody(issueType, issueNumber, titleRegex, bod if (!titleRegex && !bodyRegex) { return true; } - if (issueType === 'issue') { + if (issueType === 'issue' || issueType === 'both') { const { title, body } = await (0, utils_1.getIssueTitleAndBody)(issueNumber); if (titleRegex && !validate(titleRegex, title)) { return false; @@ -9696,7 +9696,7 @@ async function validateIssueTitleAndBody(issueType, issueNumber, titleRegex, bod } return true; } - if (issueType === 'pull_request') { + if (issueType === 'pull_request' || issueType === 'both') { const { title, body } = await (0, utils_1.getPullRequestTitleAndBody)(issueNumber); if (titleRegex && !validate(titleRegex, title)) { return false; @@ -9917,22 +9917,32 @@ async function run() { const issueType = (0, core_1.getInput)('issue-type') || 'issue'; const issueNumber = github_1.context.issue.number; const isAutoClose = (0, core_1.getInput)('auto-close') || 'false'; - isAutoClose === 'true' ? true : false; + (0, core_1.debug)(`inputs: ${JSON.stringify({ + title, + titleRegexFlags, + body, + bodyRegexFlags, + issueType, + issueNumber, + isAutoClose, + })}`); let titleRegex; let bodyRegex; - if (titleRegexFlags) { - titleRegex = new RegExp(title, titleRegexFlags); + if (titleRegexFlags === 'true') { + titleRegex = new RegExp(title); } else { titleRegex = title; } - if (bodyRegexFlags) { - bodyRegex = new RegExp(body, bodyRegexFlags); + if (bodyRegexFlags === 'true') { + bodyRegex = new RegExp(body); } else { bodyRegex = body; } + (0, core_1.debug)(`regex: ${JSON.stringify({ titleRegex, bodyRegex })}`); const result = await (0, validate_1.validateIssueTitleAndBody)(issueType, issueNumber, titleRegex, bodyRegex); + (0, core_1.debug)(`result: ${result}`); if (result === true) { (0, core_1.setOutput)('result', 'true'); } @@ -9944,7 +9954,7 @@ async function run() { owner: github_1.context.repo.owner, repo: github_1.context.repo.repo, issue_number: issueNumber, - body: `Issue #${issueNumber} is not valid: Reason: ${result}: auto closing issue...`, + body: `Issue #${issueNumber} is not valid: ${result}`, }); // Close issue await octokit.rest.issues.update({ @@ -9954,7 +9964,9 @@ async function run() { state: 'closed', }); } - (0, core_1.setOutput)('result', 'false'); + else { + (0, core_1.warning)(`Issue #${issueNumber} is not valid. Reason: ${result}`); + } } /* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unsafe-argument: 0, @typescript-eslint/no-unsafe-member-access: 0, @typescript-eslint/no-floating-promises: 0 */ } diff --git a/package.json b/package.json index 5a07b51..815d2dc 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,15 @@ { "name": "issue-validator", - "version": "0.1.0", - "main": "index.js", + "version": "0.2.5", + "main": "dist/index.js", + "scripts": { + "build": "ncc build -o dist src/index.ts --license licenses.txt", + "build:dry-run": "ncc build -o dist src/index.ts --license licenses.txt --no-cache", + "lint": "eslint . --ext .ts", + "lint:fix": "eslint . --ext .ts --fix", + "test": "jest", + "prettier": "prettier --write ." + }, "repository": "https://github.com/Okabe-Junya/issue-validator", "author": "Junya Okabe ", "license": "MIT", @@ -31,12 +39,5 @@ "ts-jest": "^29.1.1", "typescript": "^5.2.2", "typescript-eslint": "^0.0.1-alpha.0" - }, - "scripts": { - "build": "ncc build src/index.ts -o dist --license licenses.txt", - "lint": "eslint . --ext .ts", - "lint:fix": "eslint . --ext .ts --fix", - "test": "jest", - "prettier": "prettier --write ." } }