Automatizando CI/CD com GitHub Issues e Actions

Gerenciar tarefas repetitivas no desenvolvimento de software, como lidar com aprovações e acionar fluxos de trabalho de CI/CD, pode ser simplificado. O IssueOps com GitHub Actions surge como uma metodologia para automatizar essas tarefas diretamente no GitHub Issues, transformando-o em uma central de comando para automação. Seja você um desenvolvedor solo ou parte de uma equipe, o IssueOps otimiza operações sem sair do seu repositório, tornando o processo mais eficiente e produtivo.

O IssueOps utiliza o GitHub Issues, GitHub Actions e pull requests (PR) como interface para automatizar fluxos de trabalho. Em vez de alternar entre ferramentas ou acionar ações manualmente, você pode usar comentários, rótulos e mudanças de estado nas issues para iniciar pipelines de CI/CD, atribuir tarefas e até mesmo implantar aplicações. Essa abordagem oferece flexibilidade e poder para automatizar tarefas repetitivas.

O que é IssueOps?

Assim como outras metodologias “*Ops” (ChatOps, ClickOps, etc.), o IssueOps é um conjunto de ferramentas, fluxos de trabalho e conceitos que, quando aplicados ao GitHub Issues, automatizam tarefas rotineiras. A flexibilidade das issues e sua relação com os pull requests criam inúmeras possibilidades, como gerenciar aprovações e implantações, simplificando seus fluxos de trabalho no GitHub.

É importante notar que IssueOps não é apenas para DevOps. Enquanto DevOps alinha desenvolvedores e operações, IssueOps é uma prática de automação de fluxo de trabalho focada no GitHub Issues. Com o IssueOps, você pode executar desde pipelines de CI/CD complexos até sistemas de reservas, desde que possa interagir com eles via API.

Por que usar IssueOps?

Utilizar IssueOps oferece muitos benefícios práticos:

* Automação orientada por eventos: Automatize fluxos de trabalho diretamente do GitHub Issues e pull requests, transformando interações cotidianas em gatilhos para GitHub Actions.
* Personalização de fluxos de trabalho: Adapte os fluxos de trabalho às necessidades da sua equipe, seja para triagem de bugs ou implantações.
* Transparência e registro: Mantenha um registro fácil de seguir de todas as ações tomadas em uma issue, com um histórico claro do que aconteceu e quando.
* Auditabilidade: Use o GitHub Issues e pull requests como fonte da verdade, garantindo que cada ação deixe um registro estruturado e auditável.

Para começar a usar IssueOps, siga este guia rápido:

1. Defina seus gatilhos: Identifique as ações que devem iniciar seus fluxos de trabalho, como abrir uma issue, adicionar um rótulo ou mesclar um pull request.
2. Configure o GitHub Actions: Use o GitHub Actions para definir o que acontece quando um evento ocorre. Por exemplo, um rótulo “deploy” pode acionar um script de implantação.
3. Teste e itere: Teste e refine seus fluxos de trabalho do IssueOps. Comece pequeno e expanda conforme necessário.

Definindo fluxos de trabalho do IssueOps com GitHub Actions

A maioria dos fluxos de trabalho do IssueOps segue um padrão básico:

1. Um usuário abre uma issue e fornece informações sobre uma solicitação.
2. A issue é validada para garantir que contém as informações necessárias.
3. A issue é enviada para processamento.
4. A aprovação é solicitada a um usuário ou equipe autorizada.
5. A solicitação é processada e a issue é fechada.

Imagine que você é um administrador de uma organização e quer reduzir a sobrecarga de gerenciar membros da equipe. Nesse caso, você pode usar o IssueOps para construir um processo automatizado de solicitação e aprovação de associação. Esse fluxo de trabalho envolveria:

1. Um usuário cria uma solicitação para ser adicionado a uma equipe.
2. A solicitação é validada.
3. A solicitação é enviada para aprovação.
4. Um administrador aprova ou nega a solicitação.
5. A solicitação é processada:

* Se aprovada, o usuário é adicionado à equipe.
* Se negada, o usuário não é adicionado à equipe.
6. O usuário é notificado do resultado.

Ao projetar seus fluxos de trabalho do IssueOps, pense neles como uma máquina de estados finitos: um modelo de como os objetos se movem através de uma série de estados em resposta a eventos externos. Dependendo das regras definidas, diferentes ações podem ocorrer em resposta a mudanças de estado. Simplificando, imagine um fluxograma.

No IssueOps, uma issue é o objeto processado por uma máquina de estados. Ela muda de estado em resposta a eventos. Conforme o objeto muda de estado, certas ações podem ser realizadas como parte de uma transição, desde que as condições (guards) sejam atendidas. Uma vez que um estado final é alcançado, a issue pode ser fechada.

Isso se divide em alguns conceitos-chave:

* Estado: Um ponto no ciclo de vida de um objeto que satisfaz certas condições.
* Evento: Uma ocorrência externa que aciona uma mudança de estado.
* Transição: Uma ligação entre dois estados que, quando percorrida por um objeto, causará a execução de certas ações.
* Ação: Uma tarefa atômica que é realizada quando uma transição é tomada.
* Guard: Uma condição que é avaliada quando um evento de gatilho ocorre. Uma transição é tomada apenas se todas as condições associadas forem atendidas.

Conceitos-chave por trás das máquinas de estado

Dividir seu fluxo de trabalho nesses componentes permite identificar casos extremos, impor condições e criar um resultado robusto e confiável.

Dentro de uma máquina de estados, um estado define o status atual de um objeto. À medida que o objeto transita pela máquina de estados, ele mudará de estado em resposta a eventos externos. Ao construir fluxos de trabalho do IssueOps, os estados comuns para issues incluem aberto, enviado, aprovado, negado e fechado. Esses estados devem ser suficientes como os principais a serem considerados ao construir nossos fluxos de trabalho em nosso exemplo de associação de equipe acima.

Em uma máquina de estados, um evento pode ser qualquer forma de interação com o objeto e seu estado atual. Ao construir seu próprio IssueOps, você deve considerar eventos tanto do ponto de vista do usuário quanto do GitHub.

Em nosso exemplo de solicitação de associação de equipe, existem vários eventos que podem acionar uma mudança de estado. A solicitação pode ser criada, enviada, aprovada, negada ou processada. Um usuário interagindo com uma issue — como adicionar rótulos, comentar ou atualizar marcos — também pode alterar seu estado. No GitHub Actions, existem muitos eventos que podem acionar seus fluxos de trabalho.

Aqui estão algumas interações, ou eventos, que afetariam nosso exemplo de fluxo de trabalho do IssueOps ao gerenciar membros da equipe:

| Solicitação | Evento | Estado |
| :—————– | :————- | :——- |
| Solicitação criada | `issues` | `opened` |
| Solicitação aprovada | `issue_comment` | `created` |
| Solicitação negada | `issue_comment` | `created` |

Como você pode ver, o mesmo gatilho de fluxo de trabalho do GitHub pode ser aplicado a vários eventos em nossa máquina de estados. Por causa disso, a validação é fundamental. Dentro de seus fluxos de trabalho, você deve verificar tanto o tipo de evento quanto as informações fornecidas pelo usuário. Nesse caso, podemos acionar condicionalmente diferentes etapas do fluxo de trabalho com base no conteúdo do evento `issue_comment`.

Uma transição é simplesmente a mudança de um estado para outro. Em nosso exemplo, por exemplo, uma transição ocorre quando alguém abre uma issue. Quando uma solicitação atende a certas condições, ou guards, a mudança de estado pode ocorrer. Quando a transição ocorre, algumas ações ou processamento também podem ocorrer. Pense nas transições como as linhas que conectam diferentes nós no diagrama de estados ou as linhas que conectam caixas em um fluxograma.

Guards são condições que devem ser verificadas antes que um evento possa acionar uma transição para um estado diferente. Em nosso caso, sabemos que os seguintes guards devem estar em vigor:

* Uma solicitação não deve transitar para um estado Aprovado, a menos que um administrador comente `.approve` na issue.
* Uma solicitação não deve transitar para um estado Negado, a menos que um administrador comente `.deny` na issue.

E depois que a solicitação é aprovada e o usuário é adicionado à equipe? Isso é referido como uma transição não protegida. Não há condições que devam ser atendidas, então a transição acontece imediatamente!

Por fim, ações são tarefas específicas que são executadas durante uma transição. Elas podem afetar o objeto em si, mas isso não é um requisito em nossa máquina de estados. Em nosso exemplo, as seguintes ações podem ocorrer em momentos diferentes:

* Os administradores são notificados de que uma solicitação foi enviada.
* O usuário é adicionado à equipe solicitada.
* O usuário é notificado do resultado.

Construindo um fluxo de trabalho de associação de equipe com IssueOps

Para construir um exemplo prático, vamos focar nos fluxos de trabalho do GitHub Actions envolvidos na automação. Há configurações adicionais de repositório e permissões discutidas detalhadamente na documentação do IssueOps.

O GitHub Issue Forms permite criar issues padronizadas e formatadas com base em um conjunto de campos de formulário. Combinado com a ação issue-ops/parser, você pode obter JSON legível por máquina a partir do Markdown do corpo da issue. Para o nosso exemplo, vamos criar um formulário simples que aceita uma única entrada: a equipe onde queremos adicionar o usuário.

“`
name: Team Membership Request
description: Submit a new membership request
title: New Team Membership Request
labels:
– team-membership
body:
– type: input
id: team
attributes:
label: Team Name
description: The team name you would like to join
placeholder: my-team
validations:
required: true
“`

Quando as issues são criadas usando este formulário, elas serão analisadas em JSON, que pode então ser passado para o resto do fluxo de trabalho do IssueOps.

“`
{
“team”: “my-team”
}
“`

Com um corpo de issue legível por máquina, podemos executar verificações de validação adicionais para garantir que as informações fornecidas sigam quaisquer regras que possamos ter em vigor. Por exemplo, não podemos adicionar automaticamente um usuário a uma equipe se a equipe ainda não existir! É aí que a ação issue-ops/validator entra em jogo. Usando um modelo de formulário de issue e um script de validação personalizado, podemos confirmar a existência da equipe com antecedência.

“`javascript
module.exports = async (field) => {
const { Octokit } = require(‘@octokit/rest’)
const core = require(‘@actions/core’)

const github = new Octokit({
auth: core.getInput(‘github-token’, { required: true })
})

try {
// Check if the team exists
core.info(`Checking if team ‘${field}’ exists`)

await github.rest.teams.getByName({
org: process.env.GITHUB_REPOSITORY_OWNER ?? ”,
team_slug: field
})

core.info(`Team ‘${field}’ exists`)
return ‘success’
} catch (error) {
if (error.status === 404) {
// If the team does not exist, return an error message
core.error(`Team ‘${field}’ does not exist`)
return `Team ‘${field}’ does not exist`
} else {
// Otherwise, something else went wrong…
throw error
}
}
}
“`

Quando incluído em nosso fluxo de trabalho do IssueOps, isso adiciona qualquer(s) erro(s) de validação ao comentário na issue.

O principal “ponto de entrada” deste fluxo de trabalho ocorre quando um usuário cria ou edita sua issue de solicitação de associação de equipe. Este fluxo de trabalho deve se concentrar fortemente na validação de quaisquer entradas do usuário! Por exemplo, o que deve acontecer se o usuário inserir uma equipe que não existe?

Em nossa máquina de estados, este fluxo de trabalho é responsável por lidar com tudo até o estado opened. Sempre que uma issue é criada, editada ou atualizada, ela irá re-executar a validação para garantir que a solicitação esteja pronta para ser processada. Neste caso, uma condição de guard adicional é introduzida. Antes que a solicitação possa ser enviada, o usuário deve comentar com `.submit` após a validação ter sido aprovada.

“`
name: Process Issue Open/Edit

on:
issues:
types:
– opened
– edited
– reopened

permissions:
contents: read
id-token: write
issues: write

jobs:
validate:
name: Validate Request
runs-on: ubuntu-latest

# This job should only be run on issues with the `team-membership` label.
if: ${{ contains(github.event.issue.labels.*.name, ‘team-membership’) }}

steps:
# This is required to ensure the issue form template and any validation
# scripts are included in the workspace.
– name: Checkout
id: checkout
uses: actions/checkout@v4

# Since this workflow includes custom validation scripts, we need to
# install Node.js and any dependencies.
– name: Setup Node.js
id: setup-node
uses: actions/setup-node@v4

# Install dependencies from `package.json`.
– name: Install Dependencies
id: install
run: npm install

# GitHub App authentication is required if you want to interact with any
# resources outside the scope of the repository this workflow runs in.
– name: Get GitHub App Token
id: token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.ISSUEOPS_APP_ID }}
private-key: ${{ secrets.ISSUEOPS_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}

# Remove any labels and start fresh. This is important because the
# issue may have been closed and reopened.
– name: Remove Labels
id: remove-label
uses: issue-ops/labeler@v2
with:
action: remove
github_token: ${{ steps.token.outputs.token }}
labels: |
validated
approved
denied
issue_number: ${{ github.event.issue.number }}
repository: ${{ github.repository }}

# Parse the issue body into machine-readable JSON, so that it can be
# processed by the rest of the workflow.
– name: Parse Issue Body
id: parse
uses: issue-ops/parser@v4
with:
body: ${{ github.event.issue.body }}
issue-form-template: team-membership.yml
workspace: ${{ github.workspace }}

# Validate early and often! Validation should be run any time an issue is
# interacted with, to ensure that any changes to the issue body are valid.
– name: Validate Request
id: validate
uses: issue-ops/validator@v3
with:
add-comment: true
github-token: ${{ steps.token.outputs.token }}
issue-form-template: team-membership.yml
issue-number: ${{ github.event.issue.number }}
parsed-issue-body: ${{ steps.parse.outputs.json }}
workspace: ${{ github.workspace }}

# If validation passes, add the validated label to the issue.
– if: ${{ steps.validate.outputs.result == ‘success’ }}
name: Add Validated Label
id: add-label
uses: issue-ops/labeler@v2
with:
action: add
github_token: ${{ steps.token.outputs.token }}
labels: |
validated
issue_number: ${{ github.event.issue.number }}
repository: ${{ github.repository }}

# The `issue-ops/validator` action will automatically notify the user that
# the request was validated. However, you can optionally add instruction
# on what to do next.
– if: ${{ steps.validate.outputs.result == ‘success’ }}
name: Notify User (Success)
id: notify-success
uses: peter-evans/create-or-update-comment@v4
with:
issue-number: ${{ github.event.issue.number }}
body: |
Hello! Your request has been validated successfully!

Please comment with `.submit` to submit this request.
“`

Depois que a issue é criada, qualquer processamento adicional é acionado usando comentários de issue — e isso pode ser feito com um fluxo de trabalho. No entanto, para tornar as coisas um pouco mais fáceis de seguir, vamos dividir isso em alguns fluxos de trabalho separados.

O primeiro fluxo de trabalho lida com o usuário enviando a solicitação. A principal tarefa que ele executa é validar o corpo da issue em relação ao modelo de formulário para garantir que ele não tenha sido modificado.

“`
name: Process Submit Comment

on:
issue_comment:
types:
– created

permissions:
contents: read
id-token: write
issues: write

jobs:
submit:
name: Submit Request
runs-on: ubuntu-latest

# This job should only be run when the following conditions are true:
#
# – A user comments `.submit` on the issue.
# – The issue has the `team-membership` label.
# – The issue has the `validated` label.
# – The issue does not have the `approved` or `denied` labels.
# – The issue is open.
if: |
startsWith(github.event.comment.body, ‘.submit’) &&
contains(github.event.issue.labels.*.name, ‘team-membership’) == true &&
contains(github.event.issue.labels.*.name, ‘approved’) == false &&
contains(github.event.issue.labels.*.name, ‘denied’) == false &&
github.event.issue.state == ‘open’

steps:
# First, we are going to re-run validation. This is important because
# the issue body may have changed since the last time it was validated.

# This is required to ensure the issue form template and any validation
# scripts are included in the workspace.
– name: Checkout
id: checkout
uses: actions/checkout@v4

# Since this workflow includes custom validation scripts, we need to
# install Node.js and any dependencies.
– name: Setup Node.js
id: setup-node
uses: actions/setup-node@v4

# Install dependencies from `package.json`.
– name: Install Dependencies
id: install
run: npm install

# GitHub App authentication is required if you want to interact with any
# resources outside the scope of the repository this workflow runs in.
– name: Get GitHub App Token
id: token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.ISSUEOPS_APP_ID }}
private-key: ${{ secrets.ISSUEOPS_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}

# Remove the validated label. This will be re-added if validation passes.
– name: Remove Validated Label
id: remove-label
uses: issue-ops/labeler@v2
with:
action: remove
github_token: ${{ steps.token.outputs.token }}
labels: |
validated
issue_number: ${{ github.event.issue.number }}
repository: ${{ github.repository }}

# Parse the issue body into machine-readable JSON, so that it can be
# processed by the rest of the workflow.
– name: Parse Issue Body
id: parse
uses: issue-ops/parser@v4
with:
body: ${{ github.event.issue.body }}
issue-form-template: team-membership.yml
workspace: ${{ github.workspace }}

# Validate early and often! Validation should be run any time an issue is
# interacted with, to ensure that any changes to the issue body are valid.
– name: Validate Request
id: validate
uses: issue-ops/validator@v3
with:
add-comment: false # Don’t add another validation comment.
github-token: ${{ steps.token.outputs.token }}
issue-form-template: team-membership.yml
issue-number: ${{ github.event.issue.number }}
parsed-issue-body: ${{ steps.parse.outputs.json }}
workspace: ${{ github.workspace }}

# If validation passed, add the validated and submitted labels to the issue.
– if: ${{ steps.validate.outputs.result == ‘success’ }}
name: Add Validated Label
id: add-label
uses: issue-ops/labeler@v2
with:
action: add
github_token: ${{ steps.token.outputs.token }}
labels: |
validated
submitted
issue_number: ${{ github.event.issue.number }}
repository: ${{ github.repository }}

# If validation succeeded, alert the administrator team so they can
# approve or deny the request.
– if: ${{ steps.validate.outputs.result == ‘success’ }}
name: Notify Admin (Success)
id: notify-success
uses: peter-evans/create-or-update-comment@v4
with:
issue-number: ${{ github.event.issue.number }}
body: |
👋 @issue-ops/admins! The request has been validated and is
ready for your review. Please comment with `.approve` or `.deny`
to approve or deny this request.
“`

Se a solicitação for negada, o usuário deverá ser notificado e a issue deverá ser fechada.

“`
name: Process Denial Comment

on:
issue_comment:
types:
– created

permissions:
contents: read
id-token: write
issues: write

jobs:
submit:
name: Deny Request
runs-on: ubuntu-latest

# This job should only be run when the following conditions are true:
#
# – A user comments `.deny` on the issue.
# – The issue has the `team-membership` label.
# – The issue has the `validated` label.
# – The issue has the `submitted` label.
# – The issue does not have the `approved` or `denied` labels.
# – The issue is open.
if: |
startsWith(github.event.comment.body, ‘.deny’) &&
contains(github.event.issue.labels.*.name, ‘team-membership’) == true &&
contains(github.event.issue.labels.*.name, ‘submitted’) == true &&
contains(github.event.issue.labels.*.name, ‘validated’) == true &&
contains(github.event.issue.labels.*.name, ‘approved’) == false &&
contains(github.event.issue.labels.*.name, ‘denied’) == false &&
github.event.issue.state == ‘open’

steps:
# This time, we do not need to re-run validation because the request is
# being denied. It can just be closed.

# However, we do need to confirm that the user who commented `.deny` is
# a member of the administrator team.
# GitHub App authentication is required if you want to interact with any
# resources outside the scope of the repository this workflow runs in.
– name: Get GitHub App Token
id: token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.ISSUEOPS_APP_ID }}
private-key: ${{ secrets.ISSUEOPS_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}

# Check if the user who commented `.deny` is a member of the
# administrator team.
– name: Check Admin Membership
id: check-admin
uses: actions/github-script@v7
with:
github-token: ${{ steps.token.outputs.token }}
script: |
try {
await github.rest.teams.getMembershipForUserInOrg({
org: context.repo.owner,
team_slug: ‘admins’,
username: context.actor,
})
core.setOutput(‘member’, ‘true’)
} catch (error) {
if (error.status === 404) {
core.setOutput(‘member’, ‘false’)
}
throw error
}

# If the user is not a member of the administrator team, exit the
# workflow.
– if: ${{ steps.check-admin.outputs.member == ‘false’ }}
name: Exit
run: exit 0

# If the user is a member of the administrator team, add the denied label.
– name: Add Denied Label
id: add-label
uses: issue-ops/labeler@v2
with:
action: add
github_token: ${{ steps.token.outputs.token }}
labels: |
denied
issue_number: ${{ github.event.issue.number }}
repository: ${{ github.repository }}

# Notify the user that the request was denied.
– name: Notify User
id: notify
uses: peter-evans/create-or-update-comment@v4
with:
issue-number: ${{ github.event.issue.number }}
body: |
This request has been denied and will be closed.

# Close the issue as not planned.
– name: Close Issue
id: close
uses: actions/github-script@v7
with:
script: |
await github.rest.issues.update({
issue_number: ${{ github.event.issue.number }},
owner: context.repo.owner,
repo: context.repo.repo,
state: ‘closed’,
state_reason: ‘not_planned’
})
“`

Finalmente, precisamos lidar com a aprovação da solicitação. Neste caso, precisamos adicionar o usuário à equipe, notificá-lo e fechar a issue.

“`
name: Process Approval Comment

on:
issue_comment:
types:
– created

permissions:
contents: read
id-token: write
issues: write

jobs:
submit:
name: Approve Request
runs-on: ubuntu-latest

# This job should only be run when the following conditions are true:
#
# – A user comments `.approve` on the issue.
# – The issue has the `team-membership` label.
# – The issue has the `validated` label.
# – The issue has the `submitted` label.
# – The issue does not have the `approved` or `denied` labels.
# – The issue is open.
if: |
startsWith(github.event.comment.body, ‘.approve’) &&
contains(github.event.issue.labels.*.name, ‘team-membership’) == true &&
contains(github.event.issue.labels.*.name, ‘submitted’) == true &&
contains(github.event.issue.labels.*.name, ‘validated’) == true &&
contains(github.event.issue.labels.*.name, ‘approved’) == false &&
contains(github.event.issue.labels.*.name, ‘denied’) == false &&
github.event.issue.state == ‘open’

steps:
# This time, we do not need to re-run validation because the request is
# being approved. It can just be processed.

# This is required to ensure the issue form template is included in the
# workspace.
– name: Checkout
id: checkout
uses: actions/checkout@v4

# We do need to confirm that the user who commented `.approve` is a member
# of the administrator team. GitHub App authentication is required if you
# want to interact with any resources outside the scope of the repository
# this workflow runs in.
– name: Get GitHub App Token
id: token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.ISSUEOPS_APP_ID }}
private-key: ${{ secrets.ISSUEOPS_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}

# Check if the user who commented `.approve` is a member of the
# administrator team.
– name: Check Admin Membership
id: check-admin
uses: actions/github-script@v7
with:
github-token: ${{ steps.token.outputs.token }}
script: |
try {
await github.rest.teams.getMembershipForUserInOrg({
org: context.repo.owner,
team_slug: ‘admins’,
username: context.actor,
})
core.setOutput(‘member’, ‘true’)
} catch (error) {
if (error.status === 404) {
core.setOutput(‘member’, ‘false’)
}
throw error
}

# If the user is not a member of the administrator team, exit the
# workflow.
– if: ${{ steps.check-admin.outputs.member == ‘false’ }}
name: Exit
run: exit 0

# Parse the issue body into machine-readable JSON, so that it can be
# processed by the rest of the workflow.
– name: Parse Issue body
id: parse
uses: issue-ops/parser@v4
with:
body: ${{ github.event.issue.body }}
issue-form-template: team-membership.yml
workspace: ${{ github.workspace }}

– name: Add to Team
id: add
uses: actions/github-script@v7
with:
github-token: ${{ steps.token.outputs.token }}
script: |
const parsedIssue = JSON.parse(‘${{ steps.parse.outputs.json }}’)

await github.rest.teams.addOrUpdateMembershipForUserInOrg({
org: context.repo.owner,
team_slug: parsedIssue.team,
username: ‘${{ github.event.issue.user.login }}’,
role: ‘member’
})

– name: Notify User
id: notify
uses: peter-evans/create-or-update-comment@v4
with:
issue-number: ${{ github.event.issue.number }}
body: |
This request has been processed successfully!

– name: Close Issue
id: close
uses: actions/github-script@v7
with:
script: |
await github.rest.issues.update({
issue_number: ${{ github.event.issue.number }},
owner: context.repo.owner,
repo: context.repo.repo,
state: ‘closed’,
state_reason: ‘completed’
})
“`

Com alguns fluxos de trabalho padronizados, você tem um processo completo baseado em issues para gerenciar a associação de equipes. Isso pode ser estendido o quanto você quiser, incluindo suporte para remover usuários, auditar acesso e muito mais. Com o IssueOps, o céu é o limite!

O melhor do IssueOps é que ele traz outro nível de automação para uma superfície que estou constantemente usando — e isso é o GitHub. Ao usar issues e pull requests como centros de controle para fluxos de trabalho, as equipes podem reduzir o atrito, melhorar a eficiência e manter tudo transparente. Seja para automatizar implantações, aprovações ou triagem de bugs, o IssueOps torna tudo possível, sem nunca sair do seu repo.

Para mais informações e exemplos, confira o repositório de documentação de código aberto IssueOps e, se quiser se aprofundar, você pode ir para a documentação do IssueOps de código aberto.

Recomenda-se começar pequeno e experimentar o que funciona melhor para você. Com um pouco de tempo, você verá seus fluxos de trabalho ficarem mais suaves a cada commit.

Este conteúdo foi auxiliado por Inteligência Artificiado, mas escrito e revisado por um humano.
Via The GitHub Blog

Leave a Comment