Skip to content

Latest commit

 

History

History
238 lines (182 loc) · 10.1 KB

File metadata and controls

238 lines (182 loc) · 10.1 KB

📋 Workflow Structure

This guide explains how agentic workflows are organized and structured within your repository.

Directory Structure

Agentic workflows are stored in the .github/workflows folder as Markdown files (*.md) and they are compiled to GitHub Actions Workflows files (*.lock.yml)

.github/
└── workflows/
  ├── weekly-research.md # Agentic Workflow
  └── weekly-research.lock.yml # Compiled GitHub Actions Workflow

Create a markdown file in .github/workflows/ with the following structure:

---
on:
  issues:
    types: [opened]

permissions:
  issues: write

tools:
  github:
    allowed: [add_issue_comment]
---

# Workflow Description

Read the issue #${{ github.event.issue.number }}. Add a comment to the issue listing useful resources and links.

then run the compile command to generate the lock file.

gh aw compile

File Organization

Your repository structure will look like this:

your-repository/
├── .github/
│   └── workflows/
│       ├── issue-responder.md        # Your source workflow
│       ├── issue-responder.lock.yml  # Generated GitHub Actions file
│       ├── weekly-summary.md         # Another source workflow
│       └── weekly-summary.lock.yml   # Generated GitHub Actions file
└── ... (other repository files)

Workflow File Format

Each workflow consists of:

  1. YAML Frontmatter: Configuration options wrapped in ---. See Frontmatter Options for details.
  2. Markdown Content: Natural language instructions for the AI

Example Workflow File

---
on:
  issues:
    types: [opened, labeled]

permissions:
  issues: write
  contents: read

engine: claude

tools:
  github:
    allowed: [get_issue, add_issue_comment, list_issue_comments]

cache:
  key: node-modules-${{ hashFiles('package-lock.json') }}
  path: node_modules

ai-reaction: "eyes"
---

# Issue Auto-Responder

Analyze the issue #${{ github.event.issue.number }} on GitHub.

1. Determine if it's a bug report, feature request, or question
2. Add appropriate labels based on the content
3. Provide a helpful initial response with:
   - Acknowledgment of the issue
   - Request for additional information if needed
   - Links to relevant documentation

Tip

Run this command to add a Copilot custom "intructions" file for Agentic Workflows to your project. It will teach Copilot how to write Agentic Workflows.
gh aw compile --instructions

Generated Files

When you run gh aw compile, the system:

  1. Reads your .md files from .github/workflows/
  2. Processes the frontmatter and markdown content
  3. Generates corresponding .lock.yml GitHub Actions workflow files
  4. Updates .gitattributes to mark generated files

Lock File Characteristics

  • Automatic Generation: Never edit .lock.yml files manually
  • Complete Workflows: Contains full GitHub Actions YAML
  • Security: Includes proper permissions and secret handling
  • MCP Integration: Sets up Model Context Protocol servers (see MCP Guide)
  • Artifact Collection: Automatically saves logs and outputs

Expressions in Markdown Content

For security reasons, agentic workflows restrict which GitHub Actions expressions can be used in markdown content. This prevents potential security vulnerabilities from unauthorized access to secrets or environment variables.

Note: These restrictions apply only to expressions in the markdown content portion of workflows. The YAML frontmatter can still use secrets and environment variables as needed for workflow configuration (e.g., env: and authentication).

Allowed Expressions

The following GitHub Actions context expressions are permitted in the markdown content:

GitHub Context Expressions

  • ${{ github.event.after }} - The SHA of the most recent commit on the ref after the push
  • ${{ github.event.before }} - The SHA of the most recent commit on the ref before the push
  • ${{ github.event.check_run.id }} - The ID of the check run that triggered the workflow
  • ${{ github.event.check_suite.id }} - The ID of the check suite that triggered the workflow
  • ${{ github.event.comment.id }} - The ID of the comment that triggered the workflow
  • ${{ github.event.deployment.id }} - The ID of the deployment that triggered the workflow
  • ${{ github.event.deployment_status.id }} - The ID of the deployment status that triggered the workflow
  • ${{ github.event.head_commit.id }} - The ID of the head commit for the push event
  • ${{ github.event.installation.id }} - The ID of the GitHub App installation
  • ${{ github.event.issue.number }} - The number of the issue that triggered the workflow
  • ${{ github.event.label.id }} - The ID of the label that triggered the workflow
  • ${{ github.event.milestone.id }} - The ID of the milestone that triggered the workflow
  • ${{ github.event.organization.id }} - The ID of the organization that triggered the workflow
  • ${{ github.event.page.id }} - The ID of the page build that triggered the workflow
  • ${{ github.event.project.id }} - The ID of the project that triggered the workflow
  • ${{ github.event.project_card.id }} - The ID of the project card that triggered the workflow
  • ${{ github.event.project_column.id }} - The ID of the project column that triggered the workflow
  • ${{ github.event.pull_request.number }} - The number of the pull request that triggered the workflow
  • ${{ github.event.release.assets[0].id }} - The ID of the first asset in a release
  • ${{ github.event.release.id }} - The ID of the release that triggered the workflow
  • ${{ github.event.release.tag_name }} - The tag name of the release that triggered the workflow
  • ${{ github.event.repository.id }} - The ID of the repository that triggered the workflow
  • ${{ github.event.review.id }} - The ID of the pull request review that triggered the workflow
  • ${{ github.event.review_comment.id }} - The ID of the review comment that triggered the workflow
  • ${{ github.event.sender.id }} - The ID of the user who triggered the workflow
  • ${{ github.event.workflow_run.id }} - The ID of the workflow run that triggered the current workflow
  • ${{ github.event.workflow_run.conclusion }} - The conclusion of the workflow run that triggered the current workflow
  • ${{ github.event.workflow_run.html_url }} - The URL of the workflow run that triggered the current workflow
  • ${{ github.event.workflow_run.head_sha }} - The head SHA of the workflow run that triggered the current workflow
  • ${{ github.event.workflow_run.run_number }} - The run number of the workflow run that triggered the current workflow
  • ${{ github.event.workflow_run.event }} - The event that triggered the workflow run that triggered the current workflow
  • ${{ github.event.workflow_run.status }} - The status of the workflow run that triggered the current workflow
  • ${{ github.actor }} - The username of the user who triggered the workflow
  • ${{ github.job }} - Job ID of the current workflow run
  • ${{ github.owner }} - The owner of the repository (user or organization name)
  • ${{ github.repository }} - The owner and repository name (e.g., octocat/Hello-World)
  • ${{ github.run_id }} - A unique number for each workflow run within a repository
  • ${{ github.run_number }} - A unique number for each run of a particular workflow in a repository
  • ${{ github.server_url }} - Base URL of the server, e.g. https://github.com
  • ${{ github.workflow }} - The name of the workflow
  • ${{ github.workspace }} - The default working directory on the runner for steps

Special Pattern Expressions

  • ${{ needs.* }} - Any outputs from previous jobs (e.g., ${{ needs.task.outputs.text }})
  • ${{ steps.* }} - Any outputs from previous steps in the same job
  • ${{ github.event.inputs.* }} - Any workflow inputs when triggered by workflow_dispatch (e.g., ${{ github.event.inputs.name }})

Prohibited Expressions

All other expressions are dissallowed.

Security Rationale

This restriction prevents:

  • Secret leakage: Prevents accidentally exposing secrets in AI prompts or logs
  • Environment variable exposure: Protects sensitive configuration from being accessed
  • Code injection: Prevents complex expressions that could execute unintended code
  • Expression injection: Prevents malicious expressions from being injected into AI prompts
  • Prompt hijacking: Stops unauthorized modification of workflow instructions through expression values
  • Cross-prompt information attacks (XPIA): Blocks attempts to leak information between different workflow executions

Validation

Expression safety is validated during compilation with gh aw compile. If unauthorized expressions are found, you'll see an error like:

error: unauthorized expressions: [secrets.TOKEN, env.MY_VAR]. 
allowed: [github.repository, github.actor, github.workflow, ...]

Example Valid Usage

# Valid expressions
Repository: ${{ github.repository }}
Triggered by: ${{ github.actor }}  
Issue number: ${{ github.event.issue.number }}
Previous output: ${{ needs.task.outputs.text }}
User input: ${{ github.event.inputs.environment }}
Workflow run conclusion: ${{ github.event.workflow_run.conclusion }}

# Invalid expressions (will cause compilation error)
Token: ${{ secrets.GITHUB_TOKEN }}
Environment: ${{ env.MY_VAR }}
Complex: ${{ toJson(github.workflow) }}

Best Practices

  • Use descriptive names: issue-responder.md, pr-reviewer.md
  • Follow kebab-case convention: weekly-summary.md
  • Avoid spaces and special characters
  • Commit source files: Always commit .md files
  • Commit generated files: Also commit .lock.yml files for transparency

Related Documentation