---
title: Workflow setup
description: Enable the Copilot action for issue events and what runs when.
---

# Workflow setup

To run Copilot on **issue** events, add a workflow that uses the `issues` trigger and passes the required inputs (at least `token`). This page describes the **events** to use and **what the action does** on each run.

## Trigger events

Use the `issues` trigger with the types you need. Common setup:

```yaml
on:
  issues:
    types: [opened, reopened, edited, labeled, unlabeled, assigned, unassigned]
```

| Event type | When it runs | Typical use |
|------------|--------------|-------------|
| `opened` | A new issue is created | Classify, link to projects, and assign members; work waits for `in-progress`. |
| `reopened` | A closed issue is reopened | Re-apply linking and assignees; an existing `in-progress` issue resumes its workflow. |
| `edited` | Issue title or body is edited | Update project/title/linking if needed. |
| `labeled` | A label is added to the issue | **Start work** when `in-progress` is added; deploy trigger when `deploy` is added. |
| `unlabeled` | A label is removed | Update state (e.g. branch already exists; deploy label removed). |
| `assigned` / `unassigned` | Assignees change | Sync with project/assignees if your flow depends on it. |

For **branch creation**, the most important event is usually **`labeled`**: when a user adds `in-progress` to an admitted issue, the Action begins work. It creates and verifies a branch when branch management is enabled, then adds `branched`. See [Branch management](/issues/branch-management).

## Minimal workflow

Create a file under `.github/workflows/` (e.g. `copilot_issue.yml`):

```yaml
name: Copilot - Issue

on:
  issues:
    types: [opened, reopened, edited, labeled, unlabeled, assigned, unassigned]

jobs:
  copilot-issues:
    name: Copilot - Issue
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v5
        with:
          persist-credentials: false

      - uses: vypdev/copilot@v3
        with:
          token: ${{ secrets.PAT }}
          project-ids: ${{ vars.PROJECT_IDS }}
```

- **`token`** is required (use a fine-grained PAT with repo and project permissions; see [Authentication](/authentication)).
- **`project-ids`** is optional but needed if you want issues (and PRs) linked to GitHub Project boards.

`copilot setup` installs the selected Issue Forms and writes the selected
workflow profile to `COPILOT_ISSUE_WORKFLOW_PROFILE`. The corresponding Action
input is `issue-workflow-profile`; manually wired workflows should pass the
same JSON value, for example:

```yaml
- uses: vypdev/copilot@v3
  with:
    token: ${{ secrets.PAT }}
    issue-workflow-profile: ${{ vars.COPILOT_ISSUE_WORKFLOW_PROFILE || '' }}
```

The setup selector defaults to `All`, then lets the operator toggle `feature`,
`bugfix`, `documentation`, `chore`, `help`, `hotfix`, and `release` with
`Space` and confirm with `Enter`. Only selected forms are installed. A blank
issue, an issue without a recognized enabled type label, or a conflict between
type labels is not converted into a Feature; the Action reports a no-op or a
configuration block. Release and hotfix issues are admitted only when the
required form headings and values are present.

Add other inputs as needed: `issue-managed-branches`, `pre-branch-sdd`, `desired-assignees-count`, `main-branch`, `development-branch`, etc. See [Configuration](/issues/configuration) and [Examples](/issues/examples).

## What runs when

1. **Admission on every trigger** (with valid `token`): The action first compares the **event actor** with the **token owner**. If they are the same, the normal pipeline completes successfully before queueing or loading issue context (see [Authentication](/authentication)); use a **bot account** for the PAT if you want full behavior when you act as a user. Valid explicit single actions still run.

   Set the optional Repository Variable `COPILOT_BOT_LOGIN` to the PAT bot's login to apply the same generic check at job admission. Event workflows triggered by that actor then consume no runner at all. If the variable is absent, the in-Action authenticated check remains fail-safe. Manual single-action workflows are intentionally separate and are not gated this way.

2. **Issue workflow admission:** Before preparing an agent or mutating the repository, Copilot validates the profile, the live issue labels, and release/hotfix form structure. Disabled or conflicting workflows fail closed; unmanaged issues are left untouched.

3. **Project linking:** If `project-ids` is set and the token has access, the issue is linked to those projects and moved to the configured column (e.g. "Todo" or "In Progress").

4. **Assignees:** If `desired-assignees-count` is set, the action assigns up to that many members (issue creator first if they belong to the org/repo, then additional members). See [Assignees and projects](/issues/assignees-and-projects).

5. **Branch creation:** After `in-progress`, the Action creates a branch for an admitted branch-bearing issue when `issue-managed-branches: true`. For eligible feature or `contract-change` issues with `pre-branch-sdd: true`, it resolves blocking questions and publishes the validated SDD as the first branch commit. It then verifies the linked remote branch and adds `branched`. See [Branch management](/issues/branch-management).

6. **Deploy trigger:** When the `deploy` label is added to an issue that has a release or hotfix type, the action **dispatches** the workflow named in `release-workflow` or `hotfix-workflow` (e.g. `release_workflow.yml`, `hotfix_workflow.yml`). Filenames must match exactly.

## Scheduled inactivity cleanup

To close issues that remain waiting for a maintainer or issue author, add
`setup/workflows/copilot_close_inactive_issues.yml` to the destination repository
or enable the `inactiveIssueClosure` feature in `copilot setup`. The template runs
every six hours and can also be started manually:

```yaml
on:
  schedule:
    - cron: '0 */6 * * *'
  workflow_dispatch:
    inputs:
      inactivity_threshold_hours:
        description: Hours without activity before closing a waiting issue
        required: false
        default: '168'
        type: string
```

The workflow invokes `single-action: close_inactive_issues_action` and needs the
write-capable `PAT` Secret. The default threshold is 168 hours (7 days); set
`INACTIVITY_THRESHOLD_HOURS` as a Repository Variable or pass
`inactivity-threshold-hours` to override it. The action uses the existing
`state:awaiting-maintainer`, `state:awaiting-issue-author`, and
`state:ai-processing` labels, which can be customized through the normal label
inputs.

## Next steps

- **[Assignees and projects](/issues/assignees-and-projects)** — Member assignment and project linking.
- **[Branch management](/issues/branch-management)** — When and how branches are created.
- **[Examples](/issues/examples)** — Full workflow YAML examples.
