diff --git a/docs/content/states-transitions/validate.mdx b/docs/content/states-transitions/validate.mdx index cd7d57bf..422adfd5 100644 --- a/docs/content/states-transitions/validate.mdx +++ b/docs/content/states-transitions/validate.mdx @@ -148,7 +148,7 @@ module.exports = async (field) => { ## New repository request Recall from the -[issue form template](https://github.com/issue-ops/docs/blob/main/examples/ISSUE_TEMPLATE/new-repository-request.yml) +[issue form template](https://github.com/issue-ops/docs/blob/main/new-repository-request-example/ISSUE_TEMPLATE/new-repository-request.yml) that the new repository request expects the following inputs: | Input | Required | Options | diff --git a/examples/validator/failure.mustache b/examples/validator/failure.mustache deleted file mode 100644 index 1374d501..00000000 --- a/examples/validator/failure.mustache +++ /dev/null @@ -1,13 +0,0 @@ -# :no_entry: **New Repository Request Rejected** - -Your request did not pass validation! Please check the following errors and fix -them by editing your original issue. - - - - -{{#each errors}} -- {{this}} -{{/each}} - - diff --git a/examples/validator/success.mustache b/examples/validator/success.mustache deleted file mode 100644 index 83d6b9de..00000000 --- a/examples/validator/success.mustache +++ /dev/null @@ -1,17 +0,0 @@ -# :tada: **New Repository Request Validated** - -Your request has been validated! The following details were parsed from your -request. - - - - -| Key | Value | -| ---------- | ---------- | -{{#each issue}} -| `{{@key}}` | {{{newlines this}}} | -{{/each}} - - - -Thank you for using IssueOps! diff --git a/examples/ISSUE_TEMPLATE/new-repository-request.yml b/new-repository-request-example/ISSUE_TEMPLATE/new-repository-request.yml similarity index 100% rename from examples/ISSUE_TEMPLATE/new-repository-request.yml rename to new-repository-request-example/ISSUE_TEMPLATE/new-repository-request.yml diff --git a/examples/validator/config.yml b/new-repository-request-example/validator/config.yml similarity index 100% rename from examples/validator/config.yml rename to new-repository-request-example/validator/config.yml diff --git a/examples/validator/repo_doesnt_exist.js b/new-repository-request-example/validator/repo_doesnt_exist.js similarity index 100% rename from examples/validator/repo_doesnt_exist.js rename to new-repository-request-example/validator/repo_doesnt_exist.js diff --git a/examples/validator/team_exists.js b/new-repository-request-example/validator/team_exists.js similarity index 100% rename from examples/validator/team_exists.js rename to new-repository-request-example/validator/team_exists.js diff --git a/examples/validator/topics_valid.js b/new-repository-request-example/validator/topics_valid.js similarity index 100% rename from examples/validator/topics_valid.js rename to new-repository-request-example/validator/topics_valid.js diff --git a/new-repository-request-example/workflows/issue-comment.yml b/new-repository-request-example/workflows/issue-comment.yml new file mode 100644 index 00000000..9cc206ba --- /dev/null +++ b/new-repository-request-example/workflows/issue-comment.yml @@ -0,0 +1,174 @@ +name: Issue Comment + +# This workflow runs any time a comment is added to an issue. The comment body +# is read and used to determine what action to take. +on: + issue_comment: + types: + - created + +jobs: + validate: + name: Validate Request + runs-on: ubuntu-latest + + # Only run when the following conditions are true: + # - The issue has the `issueops:new-repository` label + # - The issue has the `issueops:validated` label + # - The issue does not have the `issueops:approved` label + # - The issue is open + if: | + contains(github.event.issue.labels.*.name, 'issueops:new-repository') && + contains(github.event.issue.labels.*.name, 'issueops:validated') && + contains(github.event.issue.labels.*.name, 'issueops:approved') == false && + github.event.issue.state == 'open' + + permissions: + contents: read + id-token: write + issues: write + + outputs: + request: ${{ steps.parse.outputs.request }} + + steps: + - name: Remove Labels + id: remove-label + uses: issue-ops/labeler@vX.X.X + with: + action: remove + issue_number: ${{ github.event.issue.number }} + labels: | + issueops:validated + issueops:submitted + + - name: Get App Token + id: token + uses: actions/create-github-app-token@vX.X.X + with: + app_id: ${{ secrets.MY_GITHUB_APP_ID }} + private_key: ${{ secrets.MY_GITHUB_APP_PEM }} + owner: ${{ github.repository_owner }} + + - name: Checkout + id: checkout + uses: actions/checkout@vX.X.X + + - name: Setup Node.js + id: setup-node + uses: actions/setup-node@vX.X.X + with: + node-version: 20 + cache: npm + + - name: Install Packages + id: npm + run: npm ci + + - name: Parse Issue + id: parse + uses: issue-ops/parser@vX.X.X + with: + body: ${{ github.event.issue.body }} + issue-form-template: new-repository-request.yml + + - name: Validate Issue + id: validate + uses: issue-ops/validator@vX.X.X + with: + issue-form-template: new-repository-request.yml + github-token: ${{ steps.token.outputs.token }} + parsed-issue-body: ${{ steps.parse.outputs.json }} + + - if: ${{ steps.validate.outputs.result == 'success' }} + name: Add Validated Label + id: add-label + uses: issue-ops/labeler@vX.X.X + with: + action: add + issue_number: ${{ github.event.issue.number }} + labels: | + issueops:validated + + approve: + name: Approve Request + runs-on: ubuntu-latest + + # Only run after validation has completed. + needs: validate + + steps: + - name: Approve Command + id: approve + uses: github/command@vX.X.X + with: + allowed_contexts: issue + allowlist: octo-org/approvers + allowlist_pat: ${{ secrets.MY_TOKEN }} + command: .approve + + # Create the repository. + - if: ${{ steps.approve.outputs.continue == 'true' }} + name: Create Repository + id: create + uses: actions/github-script@vX.X.X + with: + github-token: ${{ secrets.MY_TOKEN }} + script: | + const request = JSON.parse('${{ needs.validate.outputs.request }}') + await github.rest.repos.createInOrg({ + org: '${{ github.repository_owner }}', + name: request.name, + }) + + # Comment on the issue to let the user know their request was denied. + - if: ${{ steps.approve.outputs.continue == 'true' }} + name: Post Comment + id: comment + uses: peter-evans/create-or-update-comment@vX.X.X + with: + issue-number: ${{ github.event.issue.number }} + body: + ':tada: This request has been approved! Your repository has been + created.' + + # Close the issue. + - if: ${{ steps.approve.outputs.continue == 'true' }} + name: Close Issue + id: close + run: gh issue close ${{ github.event.issue.number }} --reason completed + + deny: + name: Deny Request + runs-on: ubuntu-latest + + # Only run after validation has completed. + needs: validate + + steps: + - name: Deny Command + id: deny + uses: github/command@vX.X.X + with: + allowed_contexts: issue + allowlist: octo-org/approvers + allowlist_pat: ${{ secrets.MY_TOKEN }} + command: .deny + + # Comment on the issue to let the user know their request was denied. + - if: ${{ steps.deny.outputs.continue == 'true' }} + name: Post Comment + id: comment + uses: peter-evans/create-or-update-comment@vX.X.X + with: + issue-number: ${{ github.event.issue.number }} + body: + ':no_entry_sign: This request has been denied! This issue will be + closed shortly.' + + # Close the issue. + - if: ${{ steps.deny.outputs.continue == 'true' }} + name: Close Issue + id: close + run: + gh issue close ${{ github.event.issue.number }} --reason not_planned diff --git a/examples/workflows/issue-opened.yml b/new-repository-request-example/workflows/issue-opened.yml similarity index 100% rename from examples/workflows/issue-opened.yml rename to new-repository-request-example/workflows/issue-opened.yml