diff --git a/.github/workflows/continuous-delivery.yml b/.github/workflows/continuous-delivery.yml index a0e0b046..ad97260b 100644 --- a/.github/workflows/continuous-delivery.yml +++ b/.github/workflows/continuous-delivery.yml @@ -19,7 +19,7 @@ permissions: jobs: build: - name: Build Gatsby Site + name: Build Site runs-on: ubuntu-latest # Only run this job if it was done manually or the PR was merged @@ -43,18 +43,20 @@ jobs: - name: Setup Pages id: pages uses: actions/configure-pages@v5 + + # prettier-ignore + - name: Restore Cache + id: cache + uses: actions/cache@v4 with: - static_site_generator: gatsby - generator_config_file: docs/gatsby-config.ts + path: .next/cache + key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }} + restore-keys: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}- - name: Install Dependencies id: install run: npm ci - - name: Install Playwright - id: playwright - run: npx playwright install - - name: Build id: build env: @@ -65,7 +67,7 @@ jobs: id: upload uses: actions/upload-pages-artifact@v3 with: - path: ./docs/public + path: ./out deploy: name: Deploy to GitHub Pages diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index a7a63c85..bbc3403d 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -33,10 +33,6 @@ jobs: id: install run: npm install - - name: Install Playwright - id: playwright - run: npx playwright install - - name: Check Format id: format-check run: npm run format:check diff --git a/.gitignore b/.gitignore index 98b5d665..5ef6a520 100644 --- a/.gitignore +++ b/.gitignore @@ -1,96 +1,41 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. -# Runtime data -pids -*.pid -*.seed -*.pid.lock +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov +# testing +/coverage -# Coverage directory used by tools like istanbul -coverage -*.lcov +# next.js +/.next/ +/out/ -# nyc test coverage -.nyc_output +# production +/build -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript +# misc +.DS_Store +*.pem -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* -# Dependency directories -node_modules/ -jspm_packages/ +# env files (can opt-in for committing if needed) +.env* -# TypeScript v1 declaration files -typings/ +# vercel +.vercel -# TypeScript cache +# typescript *.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env -.env.test - -# parcel-bundler cache (https://parceljs.org/) -.cache - -# next.js build output -.next - -# nuxt.js build output -.nuxt - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# Gatsby -public/ - -# macOS -.DS_Store - -scripts/ +next-env.d.ts diff --git a/.mega-linter.yml b/.mega-linter.yml index 6ad93fba..47c62e9d 100644 --- a/.mega-linter.yml +++ b/.mega-linter.yml @@ -20,6 +20,7 @@ DISABLE: # List of disabled linters keys # https://megalinter.io/latest/config-activation/ DISABLE_LINTERS: + - CSS_STYLELINT - JSON_NPM_PACKAGE_JSON_LINT - MARKDOWN_MARKDOWN_TABLE_FORMATTER - REPOSITORY_GRYPE diff --git a/.prettierignore b/.prettierignore index 680df18f..a5423a41 100644 --- a/.prettierignore +++ b/.prettierignore @@ -11,3 +11,12 @@ node_modules/ dist/ coverage/ fixtures/ +.gitattributes +.gitignore +.node-version +.prettierignore +CODEOWNERS +LICENSE +favicon.ico +.nojekyll +*.png \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fbfc23db..2a9cd377 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,16 +23,3 @@ The maintainers of this repository will review your changes and provide any feedback. Once approved, they will be merged in and a new version of the site will be deployed. You'll also be able to see your GitHub profile tagged in the contributors list for any pages you contribute to! - -## Theme - -This repository uses [Gatsby](https://www.gatsbyjs.com/), along with the -following themes and components: - -- [Primer Design System](https://primer.style/design/) -- [Primer React](https://primer.style/react/) -- [Doctocat](https://primer.style/doctocat/) - -A modified version of the Doctocat theme is used to build the documentation from -`.mdx` files in the `docs` directory. Make sure to check out the above links to -get familiarized with Gatsby, Primer, and React :smile: diff --git a/components.json b/components.json new file mode 100644 index 00000000..4e3cb470 --- /dev/null +++ b/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "tailwind.config.ts", + "css": "src/app/globals.css", + "baseColor": "slate", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "iconLibrary": "lucide" +} diff --git a/docs/.eslintrc.yml b/docs/.eslintrc.yml deleted file mode 100644 index 5b72e8b5..00000000 --- a/docs/.eslintrc.yml +++ /dev/null @@ -1,36 +0,0 @@ -env: - node: true - es6: true - jest: true - -globals: - Atomics: readonly - SharedArrayBuffer: readonly - -ignorePatterns: - - .cache - - node_modules - - public - -parser: eslint-mdx - -extends: - - plugin:mdx/recommended - - plugin:prettier/recommended - - plugin:react/recommended - -parserOptions: - extensions: - - mdx - markdownExtensions: - - md - ignoreRemarkConfig: false - -settings: - mdx/code-blocks: true - mdx/remark: true - react: - version: detect - -rules: - react/no-unescaped-entities: off diff --git a/docs/.remarkrc.yml b/docs/.remarkrc.yml deleted file mode 100644 index bca5b23c..00000000 --- a/docs/.remarkrc.yml +++ /dev/null @@ -1,13 +0,0 @@ -settings: - bullet: '-' - closeAtx: false - emphasis: '_' - fences: true - incrementListMarker: false - strong: '*' -plugins: - - remark-preset-lint-consistent - - remark-preset-lint-markdown-style-guide - - remark-preset-prettier - - - remark-lint-maximum-heading-length - - false diff --git a/docs/content/404.mdx b/docs/content/404.mdx deleted file mode 100644 index 55956200..00000000 --- a/docs/content/404.mdx +++ /dev/null @@ -1,10 +0,0 @@ -export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' -import { Box } from '@primer/react' - - - -![Supportcat](./images/supportcat.png) - -Uh oh...this page doesn't exist! - - diff --git a/docs/content/index.mdx b/docs/content/index.mdx deleted file mode 100644 index f1ea720f..00000000 --- a/docs/content/index.mdx +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: IssueOps Docs -status: Alpha ---- - -export { HeroLayout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' -import Alert from '@mui/material/Alert' -import { - LockIcon, - PencilIcon, - SearchIcon, - ZapIcon -} from '@primer/octicons-react' - -If you landed on this page, you're probably trying to find the answer to the -question _"What is IssueOps?"_ If so, you came to the right place! The goal of -this site is to provide education, best practices, examples, and resources for -building IssueOps workflows on GitHub. - - - This site is a work in progress. If you have any feedback, please [open an - issue](https://github.com/issue-ops/docs/issues/new)! If you're interested in - contributing, check out our [contribution - guide](https://github.com/issue-ops/docs/blob/main/CONTRIBUTING.md). - - -## What is IssueOps? - -IssueOps is a loose collection of tools, workflows, and concepts that can be -applied to [GitHub Issues](https://github.com/features/issues) to drive a nearly -limitless number of workflows. Like many of the other "Ops" tools, (ChatOps, -GitOps, and so on), IssueOps leverages a friendly interface to drive -behind-the-scenes automation. In this case, issues and pull requests (PRs) are -the interface, and GitHub Actions is the automation engine. - -IssueOps isn't just a DevOps tool! You can run anything from complex CI/CD -pipelines to a bed and breakfast reservation system. If you can interact with it -via an API, there's a good chance you can build it with IssueOps :wink: - -{/* TODO: Animation of IssueOps example */} - -## Why should I use IssueOps? - -### Event-driven - -Any time a user interacts with an issue or PR, an event is triggered. These -events can be used to trigger GitHub Actions workflows. - -### Customizable - -Based on the event type and data provided, you can implement custom logic to -perform virtually any task. If you can interact with it via an API, command-line -tool, or script, you can probably build it with IssueOps. - -### Transparent - -All actions taken on an issue are recorded in the issue timeline. - -### Immutable - -An issue or pull request creates an immutable record of the transaction, -approvals, and actions that are taken. This follows GitHub's _"everything has a -URL"_ philosophy. - -## How do I get started? - -Check out the resources on this site to learn more about IssueOps and how to -build your own workflows. - -If you're looking for inspiration and a practical demonstration, check out -[Bear Creek Honey Farm](https://issue-ops.github.io/bear-creek-honey-farm/)! -This is a fictional bed and breakfast reservation system drive by IssueOps -workflows. The source code for this example can be found in the -[`issue-ops/bear-creek-honey-farm`](https://github.com/issue-ops/bear-creek-honey-farm) -and -[`issue-ops/demo-reservation-action`](https://github.com/issue-ops/demo-reservation-action) -repositories. - - - If you have an interesting IssueOps project you'd like featured, send us a PR! - diff --git a/docs/content/introduction/best-practices.mdx b/docs/content/introduction/best-practices.mdx deleted file mode 100644 index 6ece3c9f..00000000 --- a/docs/content/introduction/best-practices.mdx +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Best practices -description: The dos and dont's of IssueOps -status: Alpha ---- - -export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' -import { - Do, - DoDontContainer, - Dont -} from '@issue-ops/gatsby-theme-doctocat-typescript' -import { PersonIcon } from '@primer/octicons-react' -import { StateLabel, Timeline } from '@primer/react' - -## GitHub APIs - - - Use GitHub Apps for accessing organization-level APIs - Use personal access tokens - - -## Sensitive information - - - - Use issue forms inputs that accept references to sensitive information in - secure locations - - Accept sensitive information directly in issues - - -## Validation - - - - Validate issue and comment text at every step in the IssueOps workflow - - - Rely on labels to determine if an issue has been validated or approved - - diff --git a/docs/content/introduction/index.mdx b/docs/content/introduction/index.mdx deleted file mode 100644 index 11682145..00000000 --- a/docs/content/introduction/index.mdx +++ /dev/null @@ -1,413 +0,0 @@ ---- -title: About -description: - IssueOps is a framework for using GitHub issues and pull requests as part of - workflows -status: Alpha ---- - -export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' -import Alert from '@mui/material/Alert' -import Paper from '@mui/material/Paper' -import Table from '@mui/material/Table' -import TableBody from '@mui/material/TableBody' -import TableCell from '@mui/material/TableCell' -import TableContainer from '@mui/material/TableContainer' -import TableHead from '@mui/material/TableHead' -import TableRow from '@mui/material/TableRow' -import { BookIcon, PersonIcon } from '@primer/octicons-react' -import { Avatar, Box, StateLabel, Timeline } from '@primer/react' -import { Blankslate } from '@primer/react/drafts' - -## Issues and pull requests - -In GitHub, a pull request (PR) can be interacted with in a lot of the same ways -as an issue. For example, the -[List repository issues](https://docs.github.com/en/free-pro-team@latest/rest/issues/issues?apiVersion=2022-11-28#list-repository-issues) -REST API will return both issues and PRs for a repository. - -This means that many of the features of an issue are applicable to a PR. -However, PRs have some extra functionality that can also be used in an IssueOps -workflow. Depending on the use-case, you might want to select one over the -other. For example, if you want to use the review and approval functionality for -changes to repository contents, you'll need to use a PR. If you want to use the -[issue forms](https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-issue-forms) -feature, you'll need to use an issue. - -For more information on their structure and usage in IssueOps, see -[Issues and PRs](/introduction/issues-and-prs). - -## IssueOps concept - -Think of IssueOps as a -[state diagram](https://en.wikipedia.org/wiki/State_diagram). An issue is the -_object_ that changes state in response to specific _events_. As the object -changes state, certain _actions_ may be performed as part of the _transition_ -(provided any _guard_ conditions are met). Once an _end state_ is reached, the -issue is considered complete and can be closed. - -### State Diagrams - -The following sections contain definitions and examples of common terms used in -state diagrams. These terms are used throughout this documentation. - -#### Action - -An atomic task that is performed when a transition is taken. - - - - - - @mona has invited you to collaborate - - -#### Event - -An external occurrence that triggers a state change. - - - - - - - @octocat self-assigned this - - - -#### Guard - -A condition that is evaluated when a trigger event occurs. A transition is taken -only if all associated guard conditions are met. - -#### State - -A point in an object's lifecycle that satisfies certain condition(s). - - - Open - - -#### Transition - -A link between two states that, when traversed by an object, will cause certain -action(s) to be performed. - -## IssueOps workflow - -In general, an IssueOps workflow will follow the same basic pattern: - -1. A user opens an issue and provides information about a request -1. The issue is validated to ensure it contains the required information -1. (Optional) Approval is requested from an authorized user or team -1. The request is processed and the issue is closed - -Let's use a more practical example... - -### Example: GitHub team membership - -_**User Story:**_ As a developer, I should be able to request membership to -various teams and, if approved by administrators, be granted membership. - -Suppose you are an admin of an organization and would like to reduce the -overhead of managing team membership. You can use IssueOps to build an automated -membership request and approval process. - -We can assume the current, manual workflow looks something like this when -rendered as a state diagram. - - - In state diagram format, nodes represent the state of an object (the - membership request), while transitions represent actions that are taken as the - object changes state. - - - - -```mermaid -stateDiagram-v2 - 1 : Opened - 2 : Submitted - 3 : Approved - 4 : Denied - 5 : Closed - [*] --> 1 - 1 --> 2 : Submit request - 2 --> 3 : Approve request - 2 --> 4 : Deny request - 3 --> 5 : Add to team - 4 --> 5 : Notify user - 5 --> [*] -``` - - - -When creating an IssueOps workflow, you can use this diagram as a starting point -to determine what events should trigger state changes, how to represent those -events in issues, and what actions to take in response to state changes. - -## Event triggers - -In the membership request workflow, there are several events that trigger a -change in the request state: - -- A user submits a request -- An admin approves a request -- An admin denies a request -- A user is added to a team -- A user is notified - -In GitHub, there are many ways to trigger events. For a full list, see -[Events that trigger workflows](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows). -Here, we will focus on the events that are most relevant to IssueOps. - -### Issues - -Events related to issues seem like a good fit for IssueOps :wink: Issues -are the entrypoint to the worflow. In particular, the issue being _opened_. You -can think of this as someone coming to you and saying "Can you add me to this -team?" Until this event occurs, there's nothing to do! - -However, this is not the only issue event that can be used in a workflow. The -following table lists other -[issue events](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#issues) -and example use-cases. - - - - - - Event - Example - - - - - `opened` - Start a request workflow - - - `edited` - Re-validate a modified request - - - `deleted` - Cancel in-flight tasks for a request - - - `transferred` - Assign ownership of a request to a different team - - - `pinned` - Upgrade the severity/urgency of a request - - - `unpinned` - Downgrade the severity/urgency of a request - - - `closed` - End a request workflow - - - `reopened` - Restart a request workflow - - - `assigned` - Ping the assignee in Slack - - - `unassigned` - Ping the previous assignee in Slack - - - `labeled` - Track the current state of a request - - - `unlabeled` - Track the current state of a request - - - `locked` - - See [locking - conversations](https://docs.github.com/en/communities/moderating-comments-and-conversations/locking-conversations) - - - - `unlocked` - - See [locking - conversations](https://docs.github.com/en/communities/moderating-comments-and-conversations/locking-conversations) - - - - `milestoned` - Track requests by type to compare to team goals - - - `demilestoned` - Track requests by type to compare to team goals - - -
-
- -
- - - Access to [delete - issues](https://docs.github.com/en/organizations/managing-organization-settings/allowing-people-to-delete-issues-in-your-organization) - should be carefully controlled. If you delete an issue, you will lose all of - the information associated with it, including comments and attachments. You - will also lose this request in the history of the repository. - - -### Issue comments - -After an issue is opened, other events must take place that change the state and -drive it through the workflow. In the membership request workflow, for example, -commenting on an issue is a great way to handle state changes such as an -administrator approving or denying the request. - - - A core difference between issues and PRs is that issues do not have a built-in - approval process. However, this can be implemented using issue comments. For - more information, see [Approvals](/workflow/approvals). - - -Currently there are only three -[`issue_comment` events](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#issue_comment) -that can trigger workflows: - -- `created` -- `edited` -- `deleted` - -In all three cases, the _context_ of the comment should be taken into account to -determine how to transition the request state. For example, if only authorized -administrators are allowed to approve team membership requests, how should an -IssueOps workflow react if someone else comments with approval? - -All GitHub Actions workflow runs include important -[context information](https://docs.github.com/en/actions/learn-github-actions/contexts) -that can be accessed by your workflow. The -[`issue_comment` context](https://docs.github.com/en/webhooks/webhook-events-and-payloads#issue_comment) -can provide us with information to decide what actions to take, if any. In our -team membership workflow, we can get the user that created the comment using the -`github.event.comment.user.login` property. We can then use this to determine if -the user is authorized to approve the request. - -### Labels - -Labels are a great way to track the state of a request. You can think of these -as the nodes in a state diagram, while the transitions are the actions that are -taken as the request changes state. You can also use labels to classify the -types of requests when your repository supports more than one IssueOps workflow. -For example, in the membership request workflow, you might have the following -labels: - - - - - - Label - Description - - - - - `team-membership-request` - The type of request - - - `submitted` - - Requests that have been submitted and are pending review - - - -
-
- -Looking at this list, you may ask "why there aren't labels for `approved`, -`denied`, or `closed` states?" These states don't have any transitions that do -not lead to the issue being closed. In other words, once a request is approved -or denied, the issue will **always** reach the `closed` state, regardless of -whether it was approved or denied. If this workflow had more steps, such as -requiring multiple approvals, additional states would need to be tracked. - -As with `issue_comment` events, there are only three -[`label` events](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#label) -available: - -- `created` -- `edited` -- `deleted` - -These, however, refer to the actual creation and modification of the label -itself, so they may not apply to your workflow. You will generally use the -`issue => labeled` event instead. - - - Anyone with access to open issues can also change labels! Labels are good for - state tracking, but should not be used to determine if a request is valid! For - more information, see the [Validate](/workflow/validate) step. - - -## GitHub features - -You can leverage other GitHub features to dramatically increase the value of -IssueOps. - -### Secrets - -[Secrets](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions) -let you store sensitive information at the organization, repository, or -environment level to share with GitHub Actions workflows. You can use secrets to -store information such as API keys, passwords, or tokens. Secrets are encrypted -and only exposed to runners at runtime. You can use secrets to store information -such as API keys, passwords, or tokens that can be used to access external -resources from your workflows. - -### Projects and milestones - -Keeping track of requests, especially when you have an approval process in -place, is important. -[Projects](https://docs.github.com/en/issues/planning-and-tracking-with-projects/learning-about-projects/about-projects) -make it easy to track requests throughout their lifecycle. You can automatically -add issues as they are opened, and use lifecycle rules to keep track of the -state of requests without having to manually move them around your project -board. - -You can also combine this with -[Milestones](https://docs.github.com/en/issues/using-labels-and-milestones-to-track-work/about-milestones) -to better organize issues and PRs. For example, if your IssueOps repository -includes workflows for multiple types of requests, you can add issues for each -request type to a corresponding milestone. That way they are automatically -categorized in your project. - -[Project insights](https://docs.github.com/en/issues/planning-and-tracking-with-projects/viewing-insights-from-your-project) -give you a visual snapshot of how requests are being processed. You can create -custom graphs of to see when and how teams are using your workflows. - -### GitHub Apps - -One of the most important things to consider when creating workflows that -interact with the GitHub APIs is permissions. GitHub Actions workflows can only -interact with the repository in which they run. For example, the default -permissions do not allow GitHub Actions to manage team membership. If you are -building a workflow that interacts with resources outside of the repository it -is running in, you should consider creating an organization-level -[GitHub App](https://docs.github.com/en/apps/overview) and installing it in your -IssueOps repository. That way, you can use the permissions of the app to -interact with other resources in your organization. - -For more information, see [GitHub App](/setup/github-app) in the setup -documentation. diff --git a/docs/content/introduction/issues-and-prs.mdx b/docs/content/introduction/issues-and-prs.mdx deleted file mode 100644 index 2ae02f69..00000000 --- a/docs/content/introduction/issues-and-prs.mdx +++ /dev/null @@ -1,424 +0,0 @@ ---- -title: Issues and PRs -description: The structure of issues and pull requests -status: Alpha ---- - -export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' -import { ImageContainer } from '@issue-ops/gatsby-theme-doctocat-typescript' -import Alert from '@mui/material/Alert' -import Paper from '@mui/material/Paper' -import Table from '@mui/material/Table' -import TableBody from '@mui/material/TableBody' -import TableCell from '@mui/material/TableCell' -import TableContainer from '@mui/material/TableContainer' -import TableHead from '@mui/material/TableHead' -import TableRow from '@mui/material/TableRow' -import { MarkGithubIcon, TagIcon } from '@primer/octicons-react' -import { Avatar, Box, FormControl, TextInput, Timeline } from '@primer/react' - -This page provides an overview of the different components that make up issues -and PRs, and includes information about how each component can be used -throughout an IssueOps workflow. - -## Issues - -### Issue permissions - -Any user with read access to a repository can open an issue. - -### Issue structure - - - - - - Component - Description - - - - - Title - Title of an issue - - - Body - Main content of an issue entered by a user - - - Assignees - User(s) responsible for resolving an issue - - - Labels - Short tags that can be applied to issues - - - Milestones - Groups for issues and PRs - - - Relations - - Other issues and PRs that are related to this issue - - - - Development - Branches or PRs linked to the issue - - - Projects - Projects that are tracking the issue - - - Participants - Users who have interacted with the issue - - - Timeline - Events that have occurred on the issue - - - Comments - - Comments and replies that have been added to the issue - - - - Reactions - - Emoji reactions added to the issue and its comments - - - -
-
- -### Issue templates vs. issue forms - -Currently, GitHub supports both -[issue templates](https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository) -and -[issue forms](https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-issue-forms). -When creating IssueOps workflows, the initial issue body is where you will get a -lot of the information you need to process the issue. Depending on your -use-case, issue _templates_ may not result in the desired format, since they -allow users to overwrite or replace the entire contents of the issue body during -creation. Issue _forms_ require specific input formats and result in a more -consistent output. - -### Title - -The title of an issue is a short, concise description of the reason the issue -has been opened, such as a particular bug or piece of feedback. Typically, the -title is the first thing a user will enter when they open an issue (or they may -update it based on the initial title provided by the issue form). - -When creating an issue forms, the title can be used as a way to identify the -type of issue. For example, you can use a title like -`[Request] Team Membership: TEAM_NAME` to indicate that the issue is a request -to be added to a team. However, since this field can be modified by users, it -should not be used as a way to validate the issue. - -```yaml -title: '[Request] Team Membership: TEAM_NAME' -``` - -### Body - -The body of an issue is where your workflow will get most of the information it -needs to process the issue. When creating an issue form, you can use the body to -provide instructions to the user, and to collect information from them. For -example, you can use a markdown field to provide instructions, and then use an -input field to collect the name of the team they would like to join. - - - Any `markdown`-type fields in an issue form will not be included in the issue - body after it has been submitted by the user. - - -For information about the different types of fields that can be used, see -[Syntax for issue forms](https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-issue-forms). - -### Assignees - -Assignees are users who are responsible for resolving an issue. If your workflow -involves a review process, you can use assignees to indicate who is responsible -for reviewing the issue. You can also use assignees to indicate who is -responsible for processing the issue when manual tasks are involved. - -```yaml -assignees: - - octocat - - mona -``` - - - Issues do not support team assignees, but PRs do! - - -### Labels - -Labels are a great way to control the flow of an issue through the state(s) -you've defined. Any time a issue is commented on or updated, you can use labels -to tell where in the flow it is currently, and where it needs to go next. - -```yaml -labels: - - issueops:team-membership-request -``` - -### Milestones - -If you have certain timelines or deadlines associated with your workflow, you -can use milestones to track them. Milestones are groups of issues and pull -requests that are tracked together. They can be used to track: - -- Due date -- Completion percentage -- Open and closed issues and pull requests - -An issue cannot be added automatically to a milestone using issue forms, but you -can use GitHub Actions to add it to a milestone after it has been created. See -[IssueOps Actions](/reference/actions) in the reference for more information. - -### Relations - -When creating or commenting on issues, you can reference related issues by using -the `#` symbol followed by the issue number. For example, if you want to -reference issue 1 in another issue in the same repository, you would type `#1`. - -Relations may be useful when your workflow involves multiple issues. For -example, if you have a workflow that involves interaction with another team, you -can use relations to track the status of the other team's issue. - -### Development - -The development section of an issue is where you can track the branches and pull -requests that are associated with the issue. This can be useful if your workflow -involves creating branches or pull requests for the user. For example, if you -would like to create an IssueOps workflow for users to create new repositories -and you use an infrastructure as code service such as Terraform, you may want to -create a PR on the user's behalf that includes the new repository definition. -That way, developers don't have to learn Terraform to get new infrastructure, -and operations teams can ensure all infrastructure is created following their -requirements. - -### Projects - -GitHub Projects are dual-purpose when it comes to IssueOps. They can be used to -both track and change the state of an issue. This is especially the case when -your workflow involves manual steps that must be performed by a human. - -As a non-technical example, suppose you're planning Thanksgiving dinner with -your extended family. Everyone in the family is supposed to suggest three -dishes, prepare them, and bring them on Thanksgiving day. - -You can open issues for each dish that needs to be prepared using an issue form, -and automatically assign them to your meal project. - -```yaml -projects: - - octo-repo/1 -``` - -Within your project, you can specify columns for the state of each dish (e.g. -`New`, `Ingredients purchased`, `Ready to cook`, and `Cooked`). - - - Unfortunately, @mona can't cook (maybe one day!), so you'll need to manually - move the issues through the columns as they are assigned and prepared. - However, you can use the project to track the state of each dish, and to - communicate that state to the rest of the family! - - -### Participants - -Participants are users who have interacted with an issue. This includes the user -who opened the issue as well as users who have commented on or been assigned to -the issue. You can use participants to track who has interacted with an issue, -and to communicate with them if needed. - -### Timeline - -The timeline is a list of all of the events that have occurred on an issue, -starting from when it was first opened. Each timeline event includes a -timestamp, the origin of the event, and other useful information. - -The timeline is especially useful to verify information about an issue. For -example, if you have a workflow that requires validation of the issue body, you -can (and should!) use labels to mark the issue as validated. However, what -happens if a malicious user adds the label manually? You can use the timeline to -compare when the issue body was last updated to when the validated label was -added. If the label was added before the issue body was updated, you can -determine that the label was added manually and re-run your validation logic. - -{/* prettier-ignore */} - - - - - - ncalteen added `issueops:team-request` 1 hour ago - - - - - - github-actions added `issueops:validated` 1 hour ago - - - -### Comments - -Other than the issue body, comments are how a user will drive your IssueOps -flow. You should define keywords that your workflow looks for to trigger certain -actions. Suppose you have a workflow where a user can create a new repository. -After the issue has been validated, the user can comment on the issue with a -keyword such as “.submit” to trigger the creation of their repo. - -You can also use them to communicate information back to the user. For example, -if the issue body contains invalid or incorrect information, you can reply to -the issue stating what needs to be corrected. For example, in the screenshot, -you can see that a comment was added to the issue because the request was -missing information. - -### Reactions - -Though they don't convey as much information as a comment, adding reactions to -issues and comments are a nice way to let the user know that their input has -been received and is being processed. If needed, you can follow up with a -comment when processing is complete. - -### Example issue form - -#### Issue form template - -```yaml -name: Team Membership Request -description: Submit a request to be added to a GitHub Team -title: '[Request] Team Membership: TEAM_NAME' -labels: - - issueops:team-membership-request -assignees: - - octocat - - mona -projects: - - octo-repo/1 - -body: - - type: markdown - attributes: - value: - Welcome to GitHub! Please fill out the information below to request to - be added to a GitHub Team. Once submitted, your request will be reviewed - by the admin team. Once approved, you will be added automatically! - - type: input - id: name - attributes: - label: Team name - description: The name of the team you would like to join. - placeholder: octoteam - validations: - required: true -``` - -#### Rendered output - - - - - Add a title - - - Welcome to GitHub! Please fill out the information below to request to be - added to a GitHub Team. Once submitted, your request will be reviewed by the - admin team. Once approved, you will be added automatically! - - Team name - - The name of the team you would like to join. - - - - - - -## Pull requests - -Pull requests add extra features and metadata on top of issues. Many GitHub APIs -support interacting with both at the same time! These additional features, along -with examples of how to use them in IssueOps workflows, are listed in the -following sections. - -### PR permissions - -In order to create a pull request, the required permissions will differ based on -the location of the branch you wish to merge. - - - - - - Location - Permissions - - - - - Same repository (branch) - Write access - - - Different repository (fork) - Read access - - -
-
- -### Reviews and approvals - -Unlike issues, PRs support reviews and approvals out of the box. When changes -are ready to be merged, you can assign individuals or teams as reviewers. -[Branch protection](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches) -can also be used to enforce required reviewers and other checks before a PR can -be merged. - -When your IssueOps workflow includes changes to the contents of a repository, -using PRs instead of issues is a great option to enforce specific approval -settings without having to include additional workflows for tracking approvals -as comments. - -### Status checks - -Status checks run any time a PR is created or updated. These can range from code -quality checks to security scans and more. You can use status checks to ensure -that the changes in a PR meet your organization's standards before they are -merged. - -In an IssueOps workflow, there are two ways you can use status checks: to -validate the contents of the PR, and to validate the contents of the issue. - -Validation is a **critical** aspect to consider when designing your workflow. If -your workflow is best suited for PRs, status checks can be used to run your -validation workflow any time the PR is updated. Combined with branch protection -rules specifying required status checks, you can ensure that validation rules -pass before a PR can change states. - -### Deployments and Environments - -When a GitHub Actions workflow runs that specifies an environment, a deployment -is created. Deployments track the successful/failed status of a workflow run, -and link it to the targeted environment. - -A great example of an IssueOps workflow that uses PRs, deployments, and -environments is the branch deploy model. A detailed explanation can be found in -the [reference](/reference/branch-deployments). diff --git a/docs/content/introduction/workflow-security.mdx b/docs/content/introduction/workflow-security.mdx deleted file mode 100644 index 9fe234bd..00000000 --- a/docs/content/introduction/workflow-security.mdx +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: Workflow security -description: Important details about the security of IssueOps workflows -status: Alpha ---- - -export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' -import Alert from '@mui/material/Alert' - -## GitHub Actions workflows - -The IssueOps model makes heavy use of the `issue` and `issue_comment` triggers -in GitHub Actions workflows. - -```yaml -on: - issue_comment: - types: - - created -``` - -These triggers will only act on workflow files in the _default_ branch of your -repository. This means that pull requests cannot introduce changes to your -IssueOps workflows that would be run as part of that PR (e.g. creating a -workflow that dumps secrets to the logs). Any changes to the workflow files can -be protected with branch protection rules to ensure only verified changes make -it into your default branch. - -## Workflow permissions - -To further harden your workflow files, you should always restrict them to the -base permissions needed to run. For information about the available permissions, -see -[Assigning permissions to jobs](https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs). - - - Permissions can be assigned for the entire workflow, as well as for individual - jobs. If one job needs additional permissions, make sure to scope them to that - job only. - diff --git a/docs/content/reference/branch-deployments.mdx b/docs/content/reference/branch-deployments.mdx deleted file mode 100644 index 1d3d27bd..00000000 --- a/docs/content/reference/branch-deployments.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Branch deployments -description: Reliably ship code using IssueOps in PRs -status: Alpha ---- - -export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' - -One interesting topic to include when talking about IssueOps is branch -deployments. At a high-level, branch deployments let you run and control -deployments from your PRs. - -If you don't already know what they are, the easiest way to explain them is to -compare them to the traditional merge deploy model. In the merge deploy model: - -1. A developer creates a feature branch and commits changes. -1. The developer opens a PR to get feedback from others. -1. Once approved, the PR is merged and a deployment starts from the `main` - branch. - -This works fine, but if there are bugs in the PR, you have to either merge in -fixes or revert the commits and redeploy. In the branch deploy model, changes -are deployed from the feature branch and validated before being merged into the -`main` branch. This ensures that whatever is in `main` can be deployed at any -time. If there is a problem with the deployment from the feature branch, you can -simply redeploy `main` as-is. - -For a detailed description of the branch-deploy model, see -[`github/branch-deploy`](https://github.com/github/branch-deploy). diff --git a/docs/content/reference/examples.mdx b/docs/content/reference/examples.mdx deleted file mode 100644 index 6a86e648..00000000 --- a/docs/content/reference/examples.mdx +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: Examples -description: Example IssueOps workflows and repos from the community -status: Alpha ---- - -export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' - -Here you can find examples of IssueOps workflows and repos from the developer -community. If you have an example you'd like to share, please open a PR to add -it to this page! - -- [Create Blog Posts from Issues](https://github.com/stochastical/abstractnonsense) diff --git a/docs/content/reference/issueops-actions.mdx b/docs/content/reference/issueops-actions.mdx deleted file mode 100644 index 86361a4d..00000000 --- a/docs/content/reference/issueops-actions.mdx +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: IssueOps Actions -description: Custom GitHub Actions for IssueOps workflows -status: Alpha ---- - -export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' -import Paper from '@mui/material/Paper' -import Table from '@mui/material/Table' -import TableBody from '@mui/material/TableBody' -import TableCell from '@mui/material/TableCell' -import TableContainer from '@mui/material/TableContainer' -import TableHead from '@mui/material/TableHead' -import TableRow from '@mui/material/TableRow' - -This page contains a list of useful actions for IssueOps workflows. If you know -of any, feel free to submit a PR to add it to the list! - - - - - - Action - Description - - - - - - [`actions/add-to-project`](https://github.com/actions/add-to-project) - - Add issues to project boards - - - - [`actions/create-github-app-token`](https://github.com/actions/create-github-app-token) - - Create installation access tokens for GitHub Apps - - - - [`issue-ops/labeler`](https://github.com/issue-ops/labeler) - - Bulk add/remove labels - - - - [`issue-ops/parser`](https://github.com/issue-ops/parser) - - Parse an issue into JSON - - - - [`issue-ops/releaser`](https://github.com/issue-ops/releaser) - - Automatically create releases - - - - [`issue-ops/semver`](https://github.com/issue-ops/semver) - - Automatically handle version tags - - - - [`issue-ops/validator`](https://github.com/issue-ops/validator) - - Validate issues against custom rules - - - - [`github/command`](https://github.com/github/command) - - IssueOps commands for GitHub Actions - - -
-
diff --git a/docs/content/setup/comment-workflow.mdx b/docs/content/setup/comment-workflow.mdx deleted file mode 100644 index 9f058c05..00000000 --- a/docs/content/setup/comment-workflow.mdx +++ /dev/null @@ -1,492 +0,0 @@ ---- -title: Comment workflow setup -description: Respond to comments on IssueOps-driven issues -status: Alpha ---- - -export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' -import Alert from '@mui/material/Alert' -import Paper from '@mui/material/Paper' -import Table from '@mui/material/Table' -import TableBody from '@mui/material/TableBody' -import TableCell from '@mui/material/TableCell' -import TableContainer from '@mui/material/TableContainer' -import TableHead from '@mui/material/TableHead' -import TableRow from '@mui/material/TableRow' -import { CheckCircleIcon } from '@primer/octicons-react' -import { ActionList, Box } from '@primer/react' - -After the issue has been opened and any initial processing has been run, the -comment workflow becomes the main driver of the rest of the process. This -workflow is triggered by users commenting on issues and will do any further -processing throughout the lifecycle of the issue. - -## Event triggers - -The comment workflow should, at minimum, be triggered by creation of new -comments. The `issue_comment` trigger also supports editing and deleting -comments, which may be useful for your use-case. - -```yaml -on: - issue_comment: - - created -``` - -The flexibility with the `issue_comment` trigger lies in the comments -themselves. You can take a limitless number of actions based on user input! - - - _With great power comes great responsibility!_ - - -Be careful to not make your workflow _too_ complex. Otherwise, parsing comments -becomes particularly challenging. - - - The `issue_comment` trigger may seem misleading. This trigger applies to - comments on both issues and PRs. If you want to trigger workflows on comments - that are part of a PR _review_, use the `pull_request_comment` trigger - instead. - - -## Commands - -Good IssueOps workflows make use of _commands_ to trigger actions. These -commands are typically prefixed with a symbol, such as `.` or `/`, and are -descriptive of the action that will be taken when the command is processed. In -general, any workflow that involves processing comments should start by looking -for a specific command being run. - - - - - - Keyword - Description - - - - - `.submit` - Submit a request for approval - - - `.approve` - Approve a request - - - `.deny` - Deny a request - - -
-
- -The examples you will see throughout this documentation make heavy use of the -[`github/command`](https://github.com/github/command) action. This action makes -it easy to define your actions, who can run them, and what happens when they are -run. - -The following code block shows a basic implementation of this action as part of -a IssueOps workflow to lint a pull request. In this example, the `Lint Command` -step will run any time a user comments with `.lint` on a PR. - -```yaml -name: IssueOps Linter - -on: - issue_comment: - types: - - created - -jobs: - lint: - name: Lint Codebase - runs-on: ubuntu-latest - - # Only run on PR comments, not issue comments - if: ${{ github.event.pull_request }} - - # Minimum required permissions for the `github/command` action - permissions: - pull-requests: write - issues: write - checks: read - - steps: - - name: Lint Command - id: command - uses: github/command@vX.X.X - with: - command: .lint - - - if: ${{ steps.command.outputs.continue == 'true' }} - name: Checkout - id: checkout - uses: actions/checkout@vX.X.X - - - if: ${{ steps.command.outputs.continue == 'true' }} - name: Run Linter - id: run-linter - run: npm run lint -``` - -As you can see, the `Checkout` and `Run Linter` steps only proceed if the -`Lint Command` step's `continue` output is `'true'`. The `github/command` action -provides the `continue` output to act as a gate for the rest of the workflow. - -The high-level flow of the `github/command` action is: - -1. Check the comment body for the command keyword (`.lint`) -1. Add a reaction to the comment to indicate it was received -1. Confirm the command is allowed to run - 1. The user is authorized to run the command - 1. Required checks have passed - 1. Required reviews have been submitted -1. Collect any arguments passed to the command - -## Workflow steps - -Most comment workflows can be broken down into the following steps. Depending on -your workflow, some of these may not be required. - -1. Parse and validate the command and input(s) -1. Parse and validate the issue body -1. Check the current state -1. Check the user's permissions -1. Process the command -1. Update the issue state -1. Provide feedback to the user - -### Parse and validate the command and input(s) - -Depending on your workflow, you may need users to be able to provide additional -inputs in their comments. For example, you may want to allow users to specify a -specific branch to lint, or a specific file to run tests on. Input arguments can -also be passed into the comment body as part of a command. - -The `github/command` action can be extended to support input parameters. -Parameters must be added after the separator specified by the `param_separator` -argument (default: `|`). Suppose you want to also allow users to provide a -branch name to run linting on. Users would enter a comment like this: - -```plain -.lint | main -``` - -Within your workflow, you would need to parse the parameter value and use it to -checkout the correct branch: - -```yaml -name: IssueOps Linter - -on: - issue_comment: - types: - - created - -jobs: - lint: - name: Lint Codebase - runs-on: ubuntu-latest - - # Only run on PR comments, not issue comments - if: ${{ github.event.pull_request }} - - # Minimum required permissions for the `github/command` action - permissions: - pull-requests: write - issues: write - checks: read - - steps: - - name: Lint Command - id: command - uses: github/command@vX.X.X - with: - command: .lint - param_separator: '|' # This is the default value - - - if: ${{ steps.command.outputs.continue == 'true' }} - name: Checkout - id: checkout - uses: actions/checkout@vX.X.X - with: - ref: ${{ steps.command.outputs.params }} - - - if: ${{ steps.command.outputs.continue == 'true' }} - name: Run Linter - id: run-linter - run: npm run lint -``` - - - The `params` output is a string, not an array or object. If you need to pass - multiple parameters, you will need to include additional logic for parsing the - string. - - -### Parse and validate the issue body - - - - - - - Validate Early - - - - - - Validate Often - - - -Any time you interact with an issue, make sure to validate the body! Users can -edit the issue body at any time, so it's important to make sure you're working -with the latest information. The -[`issue-ops/parser`](https://github.com/issue-ops/parser) and -[`issue-ops/validator`](https://github.com/issue-ops/validator) actions can take -care of this for you. All you need to do is make sure they are included in your -comment processing workflows. - -```yaml -steps: - - name: Parse Issue Body - id: parse - uses: issue-ops/parser@vX.X.X - with: - body: ${{ github.event.issue.body }} - issue-form-template: my-issue-form.yml - - - name: Validate Issue Body - id: validate - uses: issue-ops/validator@vX.X.X - with: - issue-form-template: my-issue-form.yml - issue-number: ${{ github.event.issue.number }} - parsed-issue-body: ${{ steps.parse.outputs.json }} -``` - -### Check the current state - -As an issue is processed, it will move through a series of [states](/states). -The current state of an issue can be tracked via labels. - -For example, suppose you have a workflow that requires users to submit their -request after is has been validated and confirmed. You could use the following -logic to check if the issue has already been submitted. That way, the processing -that would transition the issue from `validated` to `submitted` state does not -run again. - -```yaml -# This will only run if the request has already been submitted. -if: contains(github.event.issue.labels.*.name, 'issueops:submitted') == true - -steps: - - name: Post Comment - id: comment - uses: peter-evans/create-or-update-comment@vX.X.X - with: - issue-number: ${{ github.event.issue.number }} - body: | - ':clock1: It looks like this issue has already been submitted. Sit tight!' -``` - - - Labels can be edited at any time! You want to consider checking if the state - indicated by the issue labels matches the expected state of the issue. - - -### Check the user's permissions - -By default, any user with read access to a repository can open issues and add -comments. If your IssueOps workflow involves certain authorized users being able -to perform actions (e.g. approving or denying requests), this can be a problem! -Instead, you should use the `allowlist` option in the `github/command` action to -restrict who has the ability to run certain commands. - -For example, suppose you want to only allow certain administrators to approve -requests for new repositories. The following step would only allow @octocat and -@mona to run the `.approve` command. Any other users who comment on the issue -with `.approve` will not be able to push the request through to the next state. - -```yaml -- name: Approve Command - id: approve - uses: github/command@vX.X.X - with: - command: .approve - allowlist: octocat,mona -``` - -If you want to use teams to control access, you will also need to provide a -token with `read:org` scope for the `allowlist_pat` property. For information on -creating a GitHub App and using it to generate a token in a GitHub Actions -workflow, see [GitHub App setup](/setup/github-app). - -```yaml -- uses: actions/create-github-app-token@vX.X.X - id: token - with: - app_id: ${{ secrets.MY_GITHUB_APP_ID }} - private_key: ${{ secrets.MY_GITHUB_APP_PEM }} - owner: ${{ github.repository_owner }} - -- name: Approve Command - id: approve - uses: github/command@vX.X.X - with: - command: .approve - allowlist: octo-org/admin-team - allowlist_pat: ${{ steps.token.outputs.token }} -``` - -Alternatively, you can restrict access to specific roles in your IssueOps -repository using the `permissions` property. By default, anyone with write, -maintain, or administrator access to the repository can run commands. - -```yaml -- name: Approve Command - id: approve - uses: github/command@vX.X.X - with: - command: .approve - permissions: admin,maintain # Restrict users with write access -``` - -### Process the command - -This is where the magic happens! You can use any series of actions to process -your request. For example, the -[`actions/github-script`](https://github.com/actions/github-script) action is a -great choice for interacting with GitHub APIs. - -Make sure to gate these steps using the `continue` output from the -`github/command` action! - -```yaml -- if: ${{ steps.command.outputs.continue == 'true' }} - name: Add User to Team - id: add-user - uses: actions/github-script@vX.X.X - with: - token: ${{ steps.token.outputs.token }} - script: | - const request = JSON.parse('${{ steps.parse.outputs.json }}') - - await github.rest.teams.addOrUpdateMembershipForUserInOrg({ - org: context.repo.owner, - team_slug: request.team_name, - username: '${{ github.event.issue.user.login }}', - role: 'member' - }) -``` - -### Update the issue state - -Once any processing has been completed, the issue can be transitioned to the -next state. This is done by adding or removing labels from the issue. - -For example, suppose you have a workflow that requires users to submit their -request after is has been validated and confirmed. You can use the -[`issue-ops/labeler`](https://github.com/issue-ops/labeler) action to transition -the issue from `validated` to `submitted` state. - -```yaml -- if: ${{ steps.command.outputs.continue == 'true' }} - name: Set Submitted State - id: set-submitted - uses: issue-ops/labeler@vX.X.X - with: - action: add - issue_number: ${{ github.event.issue.number }} - labels: | - issueops:submitted -``` - -### Provide feedback to the user - -Any time processing is done on an issue, its helpful to let users know: - -1. The command has been received -1. The command is being processed -1. The outcome of the processing - -The `github/command` action takes care of the first part for you. It will -automatically add a reaction to any comments that contain a command. - -```yaml -- uses: github/command@vX.X.X - id: command - with: - command: .lint - reaction: eyes -``` - -Any of the following reactions can be added: - - - - - - Value - Emoji - - - - - `+1` - :+1: - - - `-1` - :-1: - - - `laugh` - :smile: - - - `confused` - :confused: - - - `heart` - :heart: - - - `hooray` - :tada: - - - `rocket` - :rocket: - - - `eyes` - :eyes: - - -
-
- -After the command has been received, adding comments to the issue to indicate -work is being done is a great way to keep users informed. Once processing is -complete, a comment can be added to the issue to indicate the outcome. - -```yaml -- if: ${{ steps.command.outputs.continue == 'true' }} - name: Add Complete Comment - id: comment-complete - uses: peter-evans/create-or-update-comment@vX.X.X - with: - issue-number: ${{ github.event.issue.number }} - body: | - Your request has been processed! Here are the details of the request: - - - **Team:** ${{ steps.parse.outputs.json.team_name }} - - **Role:** `member` -``` diff --git a/docs/content/setup/github-app.mdx b/docs/content/setup/github-app.mdx deleted file mode 100644 index bb115d5e..00000000 --- a/docs/content/setup/github-app.mdx +++ /dev/null @@ -1,252 +0,0 @@ ---- -title: GitHub App setup -description: Control access to organization-level APIs -status: Alpha ---- - -export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' -import Alert from '@mui/material/Alert' -import Paper from '@mui/material/Paper' -import Table from '@mui/material/Table' -import TableBody from '@mui/material/TableBody' -import TableCell from '@mui/material/TableCell' -import TableContainer from '@mui/material/TableContainer' -import TableHead from '@mui/material/TableHead' -import TableRow from '@mui/material/TableRow' - -If your IssueOps workflow requires access to anything outside of the repository -it is running in, you will need to provide it with a token. This token is used -to authenticate with the GitHub API and should be scoped to the minimum -permissions needed to do the job. Tokens can be provided two ways: - -- [Personal access tokens (PAT)](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) -- [GitHub App installation tokens](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-as-a-github-app-installation) - -Since PATs are scoped to a single user, they are not recommended for use in -IssueOps workflows. GitHub Apps are a better choice because they can be scoped -to a repository or organization to provide access to the APIs you need. - - - GitHub Apps cannot currently be created at the enterprise level for access to - administrative APIs. If you need access to these APIs, you will need to use a - PAT. In these cases, creating a "machine user" account is recommended over a - personal account. - - -## Ownership - -When creating a GitHub App, you have the option to specify your personal account -or an organization as the owner. Choosing an organization as the owner allows -you to grant access to multiple repositories in the organization and simplifies -permissions management. - -## Setup - -### Create a GitHub App - -For instructions on how to create a GitHub App, see -[Creating GitHub Apps](https://docs.github.com/en/apps/creating-github-apps/about-creating-github-apps/about-creating-github-apps). - -The following settings are a good starting point for IssueOps workflows: - - - - - - Setting - Value - - - - - Name - - A clear name that describes its purpose and permissions - - - - Description - - A description of what the app does and what it can access - - - - Homepage URL - The URL to the repository with your IssueOps code - - - Webhook - Disable webhooks - - - Permissions - - Select the **minimum** permissions needed for your workflow - - - -
-
- -### Create a private key - -For instructions on how to create a private key, see -[Managing private keys for GitHub Apps](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/managing-private-keys-for-github-apps). - - - Make sure to save the private key in a secure location! - - -### Create GitHub Actions secrets - -After creating your GitHub App, you will need to create secrets that your -IssueOps workflows can use to authenticate with the GitHub API. You can create -these at the organization, repository, or environment level depending on your -needs. - -You will need to create the following secrets. Make sure to note the names you -give them as you will need to reference them in your workflows. - - - - - - Name - Description - - - - - App ID - The ID of your GitHub App - - - Private Key - The private key you created - - -
-
- -
- - - The GitHub App ID is not a sensitive value and can be stored as a variable - instead of a secret. It can be found on the settings page for your GitHub App. - - -For instructions on how to create secrets, see the following links: - -- [Creating secrets for a repository](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository) -- [Creating secrets for an environment](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-an-environment) -- [Creating secrets for an organization](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-an-organization) - -## Usage - -### Update the workflow permissions - -In any workflow that needs to authenticate as a GitHub App, the following -permissions **must** be specified at the workflow or job level. - -```yaml -permissions: - contents: read - id-token: write -``` - -### Generate the installation access token - -There are various examples and open source actions available to create -installation access tokens for GitHub Actions workflows. In this documentation, -we will use the -[`actions/create-github-app-token`](https://github.com/actions/create-github-app-token) -action. - -Within any workflow job that needs to authenticate as your GitHub App, you will -need to include the following step. - -```yaml -steps: - - uses: actions/create-github-app-token@vX.X.X - id: token - with: - app_id: ${{ secrets.MY_GITHUB_APP_ID }} - private_key: ${{ secrets.MY_GITHUB_APP_PEM }} - owner: ${{ github.repository_owner }} -``` - -Make sure to update the following: - -- Set the version (`vX.X.X`) of the action to the latest published version. -- Update the secret names to match the ones you created previously. - - - In the previous example, the `owner` property is set to the owner of the - repository where this workflow is defined. If your GitHub App is installed - under another owner, you will need to specify that instead. - - -### Use the token in your workflow - -Now that the token is being generated, you can reference it in your workflows as -an output from the token generation step! This can be referenced as -`${{ steps..outputs.token }}` (e.g. -`${{ steps.token.outputs.token }}`). - -```yaml -steps: - - uses: actions/github-script@vX.X.X - id: create-org-project - with: - github-token: ${{ steps.token.outputs.token }} - script: | - await github.rest.projects.createForOrg({ - org: 'octo-org', - name: 'My awesome project' - }) -``` - - - Make sure to check which steps in your workflow will need to use the GitHub - App token versus the workflow token. For example, if you add the `issues: - write` permission to your workflow, you do not need to use the GitHub App - token to update issues in the _same_ repository as your workflows. However, - you will need to use the GitHub App token to update issues in _other_ - repositories! - - -## Example - -The following can be used as a starting point for your own workflows. Make sure -to update the following information: - -```yaml -name: Example Workflow - -# This workflow runs any time an issue is opened or edited. -on: - issues: - types: - - opened - - edited - -jobs: - example-job: - name: Example Job - runs-on: ubuntu-latest - - permissions: - contents: read - id-token: write - - steps: - # Get the GitHub App installation access token. - - uses: actions/create-github-app-token@vX.X.X - id: token - with: - app_id: ${{ secrets.MY_GITHUB_APP_ID }} - private_key: ${{ secrets.MY_GITHUB_APP_PEM }} - owner: ${{ github.repository_owner }} - - - run: echo "Add your custom steps here!" -``` diff --git a/docs/content/setup/index.mdx b/docs/content/setup/index.mdx deleted file mode 100644 index 2042ff8a..00000000 --- a/docs/content/setup/index.mdx +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Setting up IssueOps -description: Configure your IssueOps workflow -status: Alpha ---- - -export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' - -This section will walk through the end-to-end setup process for configuring an -IssueOps workflow. This includes setup and configuration of the following: - -- [Repository](/setup/repository) -- [GitHub App](/setup/github-app) -- [Issue form](/setup/issue-form) -- [Issue workflow](/setup/issue-workflow) -- [Comment workflow](/setup/comment-workflow) diff --git a/docs/content/setup/issue-form.mdx b/docs/content/setup/issue-form.mdx deleted file mode 100644 index ff99c06b..00000000 --- a/docs/content/setup/issue-form.mdx +++ /dev/null @@ -1,147 +0,0 @@ ---- -title: Issue form setup -description: Create a standardized entrypoint for your workflow -status: Alpha ---- - -export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' -import Alert from '@mui/material/Alert' - -The first interaction point users will have with your IssueOps workflow is the -issue itself. This is where they will provide the information needed to kick off -the workflow. Because of this, it is important to make sure that the issue form -template is set up to capture all the information you need to get started. - -For more information on the supported options, see -[Syntax for issue forms](https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-issue-forms). - -## Top-level syntax - -The top-level syntax of the issue form template is used to define the title and -description that users will see when they go to create an issue in your -repository. From a usability perspective, make sure to include a description and -title that clearly explains what the user is requesting and what will happen -once they submit their issue. - - - Make sure to label your issues and assign them to projects! - - -```yaml -name: Create a new repository -description: | - Once opened, this issue will cause a new GitHub repository to be created in - the `octocat` organization. You will be granted access as a collaborator so - you can build something awesome! -labels: - - issueops:new-repository -projects: - - octocat/123 -body: - # ... -``` - -## Body syntax - -The `body` property is where you specify the inputs and any other supporting -information you need to collect from the user. Its important to make sure to -collect all the information you need to get started, but also to make sure that -the form is not too long or complicated. - - - If there's a way you can calculate certain information, consider doing that - instead of asking the user to provide additional inputs. For example, you can - get the user's GitHub username from the issue metadata - (`${{ github.event.issue.user.login }}`) instead of asking them to provide it. - - -As you are drafting your issue form template, think about the kind of data you -are requesting and the best format to use (both for user input and for automated -processing later). - -This can be confusing, because once an issue form is submitted, all the inputs -look the same. Suppose you have the following issue form template: - -```yaml -name: New Repo Request -description: Submit a request to create a new GitHub repository -title: '[Request] New Repository' -labels: - - issueops:new-repository - -body: - # Markdown type fields are not included in the submitted issue body - - type: markdown - attributes: - value: - Welcome to GitHub! Please fill out the information below to request a - new repository. Once submitted, your request will be reviewed by the - IssueOps team. If approved, the repository will be created and you will - be notified via a comment on this issue. - - type: input - id: name - attributes: - label: Repository Name - description: The name of the repository you would like to create. - placeholder: octorepo - validations: - required: true - - type: dropdown - id: visibility - attributes: - label: Repository Visibility - description: The visibility of the repository. - multiple: false - options: - - private - - public - validations: - required: true - - type: dropdown - id: topics - attributes: - label: Repository Topics - description: The topics to add to the repository. - multiple: true - options: - - octocat - - issueops - - automation - validations: - required: true - - type: checkboxes - id: confirm - attributes: - label: Confirmation - description: Do you confirm this request? - options: - - label: 'Yes' - required: true - - label: 'No' - required: false -``` - -When the user submits the issue form, it will have the following Markdown -format: - -```plain -### Repository Name - -octorepo - -### Repository Visibility - -public - -### Repository Topics - -octocat, issueops - -### Confirmation - -- [x] Yes -- [ ] No -``` - -You can see that certain inputs look the same, but are actually different types -and, depending on their values, may be processed differently. diff --git a/docs/content/setup/issue-workflow.mdx b/docs/content/setup/issue-workflow.mdx deleted file mode 100644 index 1ef036c7..00000000 --- a/docs/content/setup/issue-workflow.mdx +++ /dev/null @@ -1,144 +0,0 @@ ---- -title: Issue workflow setup -description: Perform initial processing of issues -status: Alpha ---- - -export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' - -Once a user submits your issue form, its time for GitHub Actions to run the -show! The issue workflow is responsible for performing any initial processing of -the issue such as adding labels, validating the contents, adding comments, etc. -The following sections will walk through the core structure of an issue -workflow. - -## Event triggers - -Most of the time, this workflow will only be run when an issue is opened or -edited, however there are some cases where you may want to run this workflow -when an issue is reopened. - -```yaml -on: - issues: - types: - - opened - - edited - - reopened -``` - -## Jobs - -Different request types may have different inputs. For example, a new repository -request may have different inputs than a repository transfer request. If you -decide to create multiple jobs to parse different types of requests in the same -workflow, you can use labels to control which jobs run for which types of -requests. - -You should also consider how you plan to handle processing of multiple requests -in the same workflow. - -```yaml -jobs: - new-repository-request: - name: New Repository Request - runs-on: ubuntu-latest - - # Only run for issues with the `issueops:new-repository` label. - if: contains(github.event.issue.labels.*.name, 'issueops:new-repository') - - team-membership-request: - name: Team Membership Request - runs-on: ubuntu-latest - - # Only run for issues with the `issueops:team-add` label. - if: contains(github.event.issue.labels.*.name, 'issueops:team-add') -``` - -Depending on the complexity of your workflow, you may want to isolate each type -of request to separate jobs entirely, or you may want to have jobs that handle -common tasks across multiple request types. For example, if you have IssueOps -workflows for adding and removing users from a team, there's a good chance they -both have the same input data and perform the same validation steps. In this -case, you may want to create a job that handles the common tasks, and then have -separate jobs for the unique tasks. - -```yaml -jobs: - team-request: - name: Team Management Request - runs-on: ubuntu-latest - - # Run this job for both request types - if: | - contains(github.event.issue.labels.*.name, 'issueops:team-add') || - contains(github.event.issue.labels.*.name, 'issueops:team-remove') - - outputs: - request: ${{ steps.parse.outputs.json }} - - steps: - - name: Parse Issue - id: parse - uses: issue-ops/parser@vX.X.X - with: - body: ${{ github.event.issue.body }} - issue-form-template: team-add-remove-request.yml - - - name: Validate Issue - id: validate - uses: issue-ops/validator@vX.X.X - with: - issue-form-template: team-add-remove-request.yml - parsed-issue-body: ${{ steps.parse.outputs.json }} - - team-add: - name: Team Add Request - runs-on: ubuntu-latest - - # Only run after the `team-request` job has completed - needs: team-request - - # Only run for issues with the `issueops:team-add` label. - if: contains(github.event.issue.labels.*.name, 'issueops:team-add') - - steps: - - name: Add User to Team - id: add - uses: actions/github-script@vX.X.X - with: - github-token: ${{ secrets.MY_TOKEN }} - script: | - const request = JSON.parse('${{ needs.team-request.outputs.request }}') - - await github.rest.teams.addOrUpdateMembershipForUserInOrg({ - org: request.org, - team_slug: request.team, - username: request.user - }) - - team-remove: - name: Team Remove Request - runs-on: ubuntu-latest - - # Only run after the `team-request` job has completed - needs: team-request - - # Only run for issues with the `issueops:team-remove` label. - if: contains(github.event.issue.labels.*.name, 'issueops:team-remove') - - steps: - - name: Remove User from Team - id: remove - uses: actions/github-script@vX.X.X - with: - github-token: ${{ secrets.MY_TOKEN }} - script: | - const request = JSON.parse('${{ needs.team-request.outputs.request }}') - - await github.rest.teams.removeMembershipForUserInOrg({ - org: request.org, - team_slug: request.team, - username: request.user - }) -``` diff --git a/docs/content/setup/repository.mdx b/docs/content/setup/repository.mdx deleted file mode 100644 index 6e66e8e4..00000000 --- a/docs/content/setup/repository.mdx +++ /dev/null @@ -1,221 +0,0 @@ ---- -title: Repository setup -description: Configure your repository to start using IssueOps -status: Alpha ---- - -export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' -import { - Do, - DoDontContainer, - Dont, - Note -} from '@issue-ops/gatsby-theme-doctocat-typescript' -import Paper from '@mui/material/Paper' -import Table from '@mui/material/Table' -import TableBody from '@mui/material/TableBody' -import TableCell from '@mui/material/TableCell' -import TableContainer from '@mui/material/TableContainer' -import TableHead from '@mui/material/TableHead' -import TableRow from '@mui/material/TableRow' - -This page outlines recommended configuration settings for IssueOps repositories. -For instructions on how to create a repository, see the -[GitHub documentation](https://docs.github.com/en/get-started/quickstart/create-a-repo). - -## Visibility - -IssueOps works best when your repository is accessible to users who need to -submit requests. Depending on if the repository is owned by an organization or a -user account, you can set the visibility to one of the following: - - - - - - Owner - Visibility - - - - - Organization - `public` or `internal` - - - User - `public` - - -
-
- -Alternatively, if you only want to allow specific users to submit requests, you -can set the visibility to `private` and add those users as -[collaborators](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-access-to-your-personal-repositories/inviting-collaborators-to-a-personal-repository). - -## Permissions - -Users only need `read` access to open issues! Unless there is a specific reason -to do otherwise, you should only ever need to grant `read` access. - -The primary reason to grant `write` access is if your IssueOps flow uses pull -requests instead of issues, but only if you want users to create pull requests -from branches in the _same_ repository. As an alternative, you can allow forking -of your repository and users can create pull requests from their forked -repository instead. - -## Branch protection - -[Branch protection rules](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches) -are a good idea regardless of what your repository is being used for! You should -always protect your default branch (usually `main`) and any other branches that -you want to prevent accidental changes to. - -For an IssueOps repository, you should create a branch protection rule for -`main` that enables the following: - -- Require a pull request before merging -- Require status checks to pass before merging (add any continuous integration - or testing workflows that you use) -- Require branches to be up to date before merging -- Require review from Code Owners (if your repository has a `CODEOWNERS` file) - -## GitHub Actions - -### Fork pull request workflows - -If your IssueOps workflow uses pull requests instead of issues, you must be -careful about the configuration of GitHub Actions and what permissions are -allowed for fork pull requests. The following settings can be enabled for fork -pull requests, with a description of the risks involved. - - - - - - Setting - Risk - - - - - Run workflows from fork pull requests - - Forks will have read permissions to your repository - - - - - Send write tokens to workflows from fork pull requests - - - Forks will have **write** permissions to your repository - - - - - Send secrets and variables to workflows from fork pull requests - - - Forks will have access to your secrets and variables - - - - Require approval for fork pull request workflows - - Forks will not be able to run workflows until they are approved - - - -
-
- -As you can guess, the safest option is to not allow fork pull requests to run -workflows at all. However, this may not be practical for your workflow. Here are -some recommended settings: - - - - Document required permissions for contributors to run the workflows - themselves - - Send write tokens to fork pull requests - - - - - Document the required secrets and variables and how to generate them - - - Send secrets and variables to workflows from fork pull requests - - - -One alternative to consider is to "wrap" the creation of the PR into part of -your IssueOps flow. If the content of the PR will follow a known format, you can -use a GitHub Action to create the PR on behalf of the user. This will allow you -to remove the need to allow any GitHub Actions access to fork pull requests. - -{/* TODO: Direct link to specific example */} - -### Workflow permissions - -In the repository settings, it is best to keep the base workflow permissions -limited to _Read repository contents and packages permissions_. Within each -IssueOps workflow, you can increase the permissions as needed for specific jobs. - -## Environments - -If your IssueOps workflow involves deployments or interaction with environments, -you should consider adding enviroment-specific rules to restrict deployments to -only the `main` branch. A common exception to this rule is if you are running -IssueOps workflows from pull requests, as these will be run from branches other -than `main`. - -This is also a good opportunity to further restrict access to secrets and -variables by defining them at the environment level! - -## Other considerations - -A few common questions and answers about repository setup. Most of the time, the -answer is "it depends!", but these are some things to consider. - -### Multiple IssueOps workflows in one repository - -There are some tradeoffs to consider when using one or multiple repositories to -host different IssueOps workflows. For example, suppose you have the following -workflows: - -- Team membership requests -- New repository creation requests - -If you use a single repository, one challenge you may run into is ensuring that -jobs for the team membership requests don't affect new repository requests. This -is where labels are particularly helpful! You can use labels to scope jobs to -specific requests. - -```yaml -name: Issue Opened/Edited - -on: - issues: - types: - - opened - - edited - -jobs: - new-repository-request: - name: New Repository Request - runs-on: ubuntu-latest - - # Only run for issues with the `issueops:new-repository` label. - if: contains(github.event.issue.labels.*.name, 'issueops:new-repository') - - team-membership-request: - name: Team Membership Request - runs-on: ubuntu-latest - - # Only run for issues with the `issueops:team-add` label. - if: contains(github.event.issue.labels.*.name, 'issueops:team-add') -``` diff --git a/docs/content/states-and-transitions/approve.mdx b/docs/content/states-and-transitions/approve.mdx deleted file mode 100644 index df219442..00000000 --- a/docs/content/states-and-transitions/approve.mdx +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: Approve -description: The request is approved and we can process it further. -status: Alpha ---- - -export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' - -## Overview - -In the `Approved` state, we know that the issue has been approved and we can -begin processing it. This is one of the first states in the workflow where we -can perform an _unguarded transition_. - -In our repository workflow, a request is transitioned to the `Approved` state -when an authorized user comments on the request with `.approve`. However, -immediately after reaching this state, we know we can create the repository and -close the issue (moving it to the `Closed` state). This is called an _unguarded -transition_ because there is no condition that must be met before the transition -occurs. - -The actual implementation of this transition is up to you! There are a few -recommendations to keep in mind: - -- Communication to users is always helpful! Consider leaving a comment on the - issue to let the user know that their request has been approved and what is - going to happen next. Or, comment on the issue with a summary of the changes - that have taken place. -- Even after an issue is closed, users can interact with it. If you want to - prevent this, you can - [lock the issue](https://docs.github.com/en/communities/moderating-comments-and-conversations/locking-conversations). -- Labels are a great way to organize issues. Consider adding a label to the - issue to indicate that it has been approved. -- When closing an issue, choosing an appropriate reason is useful for future - reporting. For approved requests, closing an issue as `not_planned` may be - misleading. Consider `completed` instead. - -## New repository request - -When a new repository request is approved, we need to do the following: - -1. Create the repository -1. Comment on the issue -1. Close the issue - -```yaml -# This job is responsible for handling approved requests. -deny: - 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 -``` - -## Next steps - -Your IssueOps workflow is officially complete! diff --git a/docs/content/states-and-transitions/deny.mdx b/docs/content/states-and-transitions/deny.mdx deleted file mode 100644 index 4e1cee92..00000000 --- a/docs/content/states-and-transitions/deny.mdx +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: Deny -description: The request is denied and the issue can be closed. -status: Alpha ---- - -export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' - -## Overview - -In the `Denied` state, we know that the issue has been denied and there is no -further action to take. This is one of the first states in the workflow where we -can perform an _unguarded transition_. - -In our repository workflow, a request is transitioned to the `Denied` state when -an authorized user comments on the request with `.deny`. However, immediately -after reaching this state, we want to close the issue (moving it to the `Closed` -state). This is called an _unguarded transition_ because there is no condition -that must be met before the transition occurs. - -The actual implementation of this transition is up to you! There are a few -recommendations to keep in mind: - -- Communication to users is always helpful! Consider leaving a comment on the - issue to let the user know that their request has been denied and what steps, - if any, they can take next. -- Even after an issue is closed, users can interact with it. If you want to - prevent this, you can - [lock the issue](https://docs.github.com/en/communities/moderating-comments-and-conversations/locking-conversations). -- Labels are a great way to organize issues. Consider adding a label to the - issue to indicate that it has been denied. -- When closing an issue, choosing an appropriate reason is useful for future - reporting. For denied requests, closing an issue as `completed` may be - misleading. Consider `not_planned` instead. - -## New repository request - -When a new repository request is denied, we want to close the issue and leave a -comment for the user. We should also add an appropriate label so we know the -request was closed as denied. - -```yaml -# This job is responsible for handling denied requests. -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 -``` - -## Next steps - -Your IssueOps workflow is officially complete! diff --git a/docs/content/states-and-transitions/index.mdx b/docs/content/states-and-transitions/index.mdx deleted file mode 100644 index 65793eff..00000000 --- a/docs/content/states-and-transitions/index.mdx +++ /dev/null @@ -1,191 +0,0 @@ ---- -title: States and transitions -description: - Implementation and handling of state transitions in an IssueOps workflow -status: Alpha ---- - -export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' -import { ImageContainer } from '@issue-ops/gatsby-theme-doctocat-typescript' -import Paper from '@mui/material/Paper' -import Table from '@mui/material/Table' -import TableBody from '@mui/material/TableBody' -import TableCell from '@mui/material/TableCell' -import TableContainer from '@mui/material/TableContainer' -import TableHead from '@mui/material/TableHead' -import TableRow from '@mui/material/TableRow' -import { Box } from '@primer/react' - -As the [introduction](/introduction) mentioned, IssueOps can be thought of as a -state diagram where an issue transitions through different states in response to -events and conditions. This section of the documentation describes some common -states, transitions. and how to implement them in your workflows. - -## States - -If an issue was a paper form, a state would be a big rubber stamp that tells -anyone who looks at the form exactly what is going on. - -Tracking state can be as simple as checking what labels are applied to your -issues. Whatever approach you want to take, remember that tracking state is -critical to ensure that the right processing occurs at the right time! - - - - - - State - Description - - - - - `Opened` - - The initial state for a new issue that has been opened. - - Typically the first state in the lifecycle of an issue. - - - - `Parsed` - - The issue body has been read and converted to machine-readable JSON. - - Usually the next immediate state after `Opened`. - - - - `Validated` - - The issue body has been deemed valid based on any custom rules. - - Usually the next immediate state after `Parsed`. - - The next transitions depend on the type of request and any rules that - must be followed. - - - - `Submitted` - The issue has been submitted for processing. - - - `Approved` - The issue has been approved for processing. - - - `Denied` - The issue has been denied for processing. - - - `Closed` - The issue has been closed :tada: - - - -
-
- - - -```mermaid -stateDiagram-v2 - 1 : Opened - 2 : Parsed - 3 : Validated - 4 : Submitted - 5 : Approved - 6 : Denied - 7 : Closed - [*] --> 1 - 1 --> 1 : Parse failure - 1 --> 2 : Parse success - 2 --> 2 : Validate failure - 2 --> 3 : Validate success - 3 --> 4 : Submit for processing - 4 --> 5 : Approve request - 4 --> 6 : Deny request - 5 --> 7 : Process request - 6 --> 7 : Notify user - 7 --> [*] -``` - - - -## Transitions - -If an issue was a paper form, a transition would be someone taking it out of -their inbox, stamping it **APPROVED**, and putting it in their outbox. - -Transitions are where actual processing on your issues occurs. A transition is -equivalent to an event that triggers a GitHub Actions workflow run. That is why, -as your IssueOps workflows become larger and more complex, tracking state is so -important. Otherwise, its easy to end up the wrong workflows running at the -wrong time! - -Since each transition is triggered by the same type of event: - -```yaml -on: - issue_comment: - - created -``` - -Your workflows must track the following to determine what jobs to run: - -- Issue state -- Issue body -- Comment body (command and arguments) -- Any other relevant information in the issue - -Each of the following sections describes how to implement the core transitions -in an IssueOps workflow. Throughout each page, you will see an example -implementation of a new repository request workflow. This workflow is designed -to demonstrate how to apply each concept. - -A full example can be found in the -[`issue-ops/bear-creek-honey-farm`](https://github.com/issue-ops/bear-creek-honey-farm) -and -[`issue-ops/demo-reservation-action`](https://github.com/issue-ops/demo-reservation-action) -repositories. - -- [Parse](/states-and-transitions/parse) -- [Validate](/states-and-transitions/validate) -- [Submit](/states-and-transitions/submit) -- [Approve](/states-and-transitions/approve) -- [Deny](/states-and-transitions/deny) - -## FAQ - -### Do my IssueOps need all these states? - -Nope! You can use as many or as few states as you need. For example, if you -don't need an authorized user to approve requests, you can omit the `Approved` -state. - -### Can my IssueOps use each state more than once? - -Of course! In state diagrams, its common for each state to have multiple -transitions. States can even transition back into themselves! - -When an issue is first opened it will be in the `Opened` state. Typically, the -first step after an issue is opened is to parse the body and prepare for further -processing. If this is successful, the issue would transition into the `Parsed` -state. If there is a problem during parsing, the workflow can add a comment with -a descriptive error and return the issue to the `Opened` state. When the user -edits the issue to fix the error, parsing would run again. - - - -```mermaid -stateDiagram-v2 - 1 : Opened - 2 : Parsed - [*] --> 1 - 1 --> 2 : Parse success - 1 --> 1 : Parse failure - 2 --> [*] -``` - - diff --git a/docs/content/states-and-transitions/parse.mdx b/docs/content/states-and-transitions/parse.mdx deleted file mode 100644 index 285132e2..00000000 --- a/docs/content/states-and-transitions/parse.mdx +++ /dev/null @@ -1,327 +0,0 @@ ---- -title: Parse -description: Turn the issue body into a machine readable format. -status: Alpha ---- - -export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' -import { ImageContainer } from '@issue-ops/gatsby-theme-doctocat-typescript' -import Alert from '@mui/material/Alert' -import Paper from '@mui/material/Paper' -import Table from '@mui/material/Table' -import TableBody from '@mui/material/TableBody' -import TableCell from '@mui/material/TableCell' -import TableContainer from '@mui/material/TableContainer' -import TableHead from '@mui/material/TableHead' -import TableRow from '@mui/material/TableRow' -import { Box, FormControl, Select, Textarea, TextInput } from '@primer/react' - -## Overview - -When a new issue is opened, before any action can be taken on it, you should -parse its contents and turn it into a machine-readable format. The -[`issue-ops/parser`](https://github.com/issue-ops/parser) action does this by -comparing the body of the issue with the original issue form template. This way, -you can directly reference issue form fields without having to parse the body -yourself with regular expressions. - - - This is also available as a standalone npm package, - [`@github/issue-parser`](https://www.npmjs.com/package/@github/issue-parser)! - - -This action provides specific output formats based on the `type` property of the -input. - - - - - - Input type - Example parsed output - - - - - `input` - `"octorepo"` - - - `textarea` - `"This is a description!\n\nIt is multiline, too!"` - - - `dropdown` - `["octocat", "issueops"]` - - - `checkboxes` - `{ "selected": ["Yes"], "unselected": ["No"] }` - - -
-
- -Depending on how you're processing the input data, different types may be more -helpful than others! Based on the issue form template and the contents of the -issue itself, the `json` output will look similar to the following: - -```json -{ - "the_name_of_the_thing": "this-thing", - "the_nickname_of_the_thing": "thing", - "the_color_of_the_thing": ["blue"], - "the_shape_of_the_thing": ["square"], - "the_sounds_of_the_thing": ["re", "mi"], - "the_topics_about_the_thing": [], - "the_description_of_the_thing": "This is a description.\n\nIt has lines.", - "the_notes_about_the_thing": "- Note\n- Another note\n- Lots of notes", - "the_code_of_the_thing": "const thing = new Thing()\n\nthing.doThing()", - "the_string_method_of_the_code_of_the_thing": "thing.toString()", - "is_the_thing_a_thing": { - "selected": ["Yes"], - "unselected": ["No"] - }, - "is_the_thing_useful": { - "selected": ["Sometimes"], - "unselected": ["Yes", "No"] - }, - "read_team": "IssueOps-Demo-Readers", - "write_team": "IssueOps-Demo-Writers" -} -``` - -Once an issue has been parsed, the next step is to -[validate](/states-and-transitions/validate) the contents to make sure the -request isn't missing data, doesn't contain invalid data, and can be processed -by your workflow. - -## New repository request - -### Issue form template - -The new repository worklow starts off with the following issue form template. - -```yaml -name: New Repository Request -description: Submit a request to create a new GitHub repository -title: '[Request] New Repository' -labels: - - issueops:new-repository - -body: - - type: markdown - attributes: - value: - Welcome to GitHub! Please fill out the information below to request a - new repository. Once submitted, your request will be reviewed by the - IssueOps team. If approved, the repository will be created and you will - be notified via a comment on this issue. - - type: input - id: name - attributes: - label: Repository Name - description: The name of the repository you would like to create. - placeholder: octorepo - validations: - required: true - - type: dropdown - id: visibility - attributes: - label: Repository Visibility - description: The visibility of the repository. - multiple: false - options: - - private - - public - validations: - required: true - - type: input - id: read-team - attributes: - label: Read Team - description: The GitHub Team that will get read access to the repository. - placeholder: octocat-readers - validations: - required: true - - type: input - id: write-team - attributes: - label: Write Team - description: The GitHub Team that will get write access to the repository. - placeholder: octocat-writers - validations: - required: true - - type: dropdown - id: auto-init - attributes: - label: Auto Init - description: Select `true` to initialize the repository with a `README`. - multiple: false - options: - - 'true' - - 'false' - validations: - required: true - - type: textarea - id: topics - attributes: - label: Topics - description: - (Optional) A list of topics to add to the repository. Separate each - topic with a new line. - placeholder: | - octocat - octodog - validations: - required: false -``` - -When a user submits a request for a new repository, the issue form will look -something like this: - - - - - Add a title - - - Welcome to GitHub! Please fill out the information below to request a new - repository. Once submitted, your request will be reviewed by the IssueOps - team. If approved, the repository will be created and you will be notified - via a comment on this issue. - - Repository Name - - The name of the repository you would like to create. - - - - - Repository Visibility - - The visibility of the repository. - - - - - Read Team - - The GitHub Team that will get read access to the repository. - - - - - Write Team - - The GitHub Team that will get write access to the repository. - - - - - Auto Init - - Select `true` to initialize the repository with a `README`. - - - - - Topics - - (Optional) A list of topics to add to the repository. Separate each - topic with a new line. - -