diff --git a/docs/content/introduction/best-practices.mdx b/docs/content/introduction/best-practices.mdx new file mode 100644 index 00000000..682959d9 --- /dev/null +++ b/docs/content/introduction/best-practices.mdx @@ -0,0 +1,55 @@ +--- +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, + Dont, + DoDontContainer, + Note +} from '@issue-ops/gatsby-theme-doctocat-typescript' +import { StateLabel, Timeline } from '@primer/react' +import { PersonIcon } from '@primer/octicons-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 new file mode 100644 index 00000000..7fc76cf8 --- /dev/null +++ b/docs/content/introduction/index.mdx @@ -0,0 +1,321 @@ +--- +title: Overview +description: + IssueOps is a framework for using GitHub issues and pull requests as part of + workflows +status: Beta +--- + +export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' +import { Note } from '@issue-ops/gatsby-theme-doctocat-typescript' +import { Avatar, Box, StateLabel, Timeline } from '@primer/react' +import { Blankslate } from '@primer/react/drafts' +import { BookIcon, PersonIcon } from '@primer/octicons-react' + +## 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 : Start + 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 department | +| `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 create 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 created, 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 Apps](/reference/github-apps). diff --git a/docs/content/introduction/issues-and-prs.mdx b/docs/content/introduction/issues-and-prs.mdx new file mode 100644 index 00000000..3f0cbd14 --- /dev/null +++ b/docs/content/introduction/issues-and-prs.mdx @@ -0,0 +1,89 @@ +--- +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' + +## Issues + +### Issue structure + +| Component | Format | Description | +| ------------ | -------------- | --------------------------------------------------------------------------- | +| Title | Text | The title of an issue | +| Body | Markdown | The body of an issue, either entered by the user or generated by a template | +| Assignees | List | The users assigned to the issue | +| Labels | List | The labels applied to the issue | +| Milestones | List | The milestones applied to the issue | +| Relations | List | The issues and PRs related to the issue | +| Development | List | The branches or PRs linked to the issue | +| Projects | List | The projects the issue is associated with | +| Participants | List | The users who have interacted with the issue | +| Timeline | List | The events that have occurred on the issue | +| Comments | Timeline items | The comments that have been added to the issue | +| Reactions | Timeline items | The reactions that have been added to the issue or its comments | + +### Title + +The title of an issue should be descriptive and concise. It should be easy to + +### Body + +This can be entered directly by the user, or you can enforce a desired format +using issue forms. Issue forms will help you enforce a standard format that is +easy to parse and validate. + +### Assignees + +### 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. + +### Milestones + +### Relations + +### Development + +### Projects + +### Participants + +### Timeline + +### 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. + +## Pull requests + +In a pull request, there are a couple additional features that can be used: + +### Reviews and Approvals + +Currently, issues don't include an approval functionality. If you want to +implement this in an issue, you will need to do so using comments. + +In a PR, however, you can define specific users or teams that need to approve a +request before it is completed. diff --git a/docs/content/reference/branch-deployments.mdx b/docs/content/reference/branch-deployments.mdx new file mode 100644 index 00000000..41c4dd44 --- /dev/null +++ b/docs/content/reference/branch-deployments.mdx @@ -0,0 +1,27 @@ +--- +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. 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: + +A developer creates a feature branch and commits changes. + +The developer opens a PR to get feedback from others. + +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. diff --git a/docs/content/reference/github-apps.mdx b/docs/content/reference/github-apps.mdx new file mode 100644 index 00000000..32d1743b --- /dev/null +++ b/docs/content/reference/github-apps.mdx @@ -0,0 +1,7 @@ +--- +title: GitHub Apps +description: Control access to organization-level APIs +status: Alpha +--- + +export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' diff --git a/docs/content/workflow/approve.mdx b/docs/content/workflow/approve.mdx new file mode 100644 index 00000000..d11b4971 --- /dev/null +++ b/docs/content/workflow/approve.mdx @@ -0,0 +1,7 @@ +--- +title: Approve an issue +description: Allow processing to continue +status: Alpha +--- + +export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' diff --git a/docs/content/workflow/close.mdx b/docs/content/workflow/close.mdx new file mode 100644 index 00000000..ced2e672 --- /dev/null +++ b/docs/content/workflow/close.mdx @@ -0,0 +1,7 @@ +--- +title: Close an issue +description: Mark this request as done +status: Alpha +--- + +export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' diff --git a/docs/content/workflow/create.mdx b/docs/content/workflow/create.mdx new file mode 100644 index 00000000..a833d203 --- /dev/null +++ b/docs/content/workflow/create.mdx @@ -0,0 +1,7 @@ +--- +title: Create an issue +description: The start of the IssueOps workflow +status: Alpha +--- + +export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' diff --git a/docs/content/workflow/index.mdx b/docs/content/workflow/index.mdx new file mode 100644 index 00000000..a82b6347 --- /dev/null +++ b/docs/content/workflow/index.mdx @@ -0,0 +1,7 @@ +--- +title: IssueOps workflow +description: Implementation of the IssueOps workflow +status: Alpha +--- + +export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' diff --git a/docs/content/workflow/submit.mdx b/docs/content/workflow/submit.mdx new file mode 100644 index 00000000..0b580963 --- /dev/null +++ b/docs/content/workflow/submit.mdx @@ -0,0 +1,7 @@ +--- +title: Submit an issue +description: Begin processing of the request +status: Alpha +--- + +export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' diff --git a/docs/content/workflow/validate.mdx b/docs/content/workflow/validate.mdx new file mode 100644 index 00000000..11aef103 --- /dev/null +++ b/docs/content/workflow/validate.mdx @@ -0,0 +1,37 @@ +--- +title: Validate an issue +description: Validate early, and validate often! +status: Alpha +--- + +export { Layout as default } from '@issue-ops/gatsby-theme-doctocat-typescript' + +The validation step is where you can perform any checks to ensure that the +request is valid. This is a great place to check for things like: + +Inputs for drop-down fields are one of the available options + +Inputs for text fields are in the correct format + +Inputs for checkboxes are valid + +Validation should be done early and often! After a request is initially +validated, there is nothing stopping a user from editing the issue and +submitting it with invalid inputs. Consider re-running validation logic any time +the following events happen: + +The issue is created + +The issue body is edited + +The issue is closed and reopened + +The request is submitted for provisioning/creation + +After a request is validated successfully, it's helpful to provide a summary of +the actions that will be taken when the user submits the request. However, if +you have good validation logic in place, you can probably remove this step and +move straight to requesting approval after the issue is created. However you’ll +still need to consider how to handle situations such as an admin approving the +request and the user updating the issue body (this is simple to do by checking +the comment timestamps). diff --git a/docs/src/@issue-ops/gatsby-theme-doctocat-typescript/nav.yml b/docs/src/@issue-ops/gatsby-theme-doctocat-typescript/nav.yml index 6a114d7a..a81afca0 100644 --- a/docs/src/@issue-ops/gatsby-theme-doctocat-typescript/nav.yml +++ b/docs/src/@issue-ops/gatsby-theme-doctocat-typescript/nav.yml @@ -1,32 +1,28 @@ - title: Introduction children: - - title: Getting started - url: /getting-started - - title: Gatsby CLI - url: /getting-started/gatsby-cli - - title: Examples - url: /getting-started/examples -- title: Usage + - title: Overview + url: /introduction + - title: Issues and PRs + url: /introduction/issues-and-prs + - title: Best Practices + url: /introduction/best-practices +- title: IssueOps Workflow children: - - title: Local development - url: /usage/local-development - - title: Customization - url: /usage/customization - - title: Front matter - url: /usage/front-matter - - title: Live code - url: /usage/live-code - - title: Deployment - url: /usage/deployment - - title: Using images - url: /usage/using-images -- title: Components + - title: About + url: /workflow + - title: Create + url: /workflow/create + - title: Validate + url: /workflow/validate + - title: Submit + url: /workflow/submit + - title: Approve + url: /workflow/approve + - title: Close + url: /workflow/close +- title: Reference children: - - title: Caption - url: /components/caption - - title: Do/Don't - url: /components/do-dont - - title: ImageContainer - url: /components/image-container - - title: Note - url: /components/note + - title: Branch Deployments + url: /reference/branch-deployments + - title: GitHub Apps + url: /reference/github-apps