Skip to main content

Working with Workflow Annotations

1. Creating Error Annotations

Field Description Example
job.status Indicates the status of the job (success, failure, cancelled) failure
step.name Name of the step where the error occurred Run tests
step.conclusion Conclusion of the step (success, failure, cancelled) failure
step.number Number of the step in the job 3

Example: Using GitHub Actions Error Annotations

echo "::error file=main.js,line=10,col=5::Failed to parse JSON"

Example: Annotating with Custom Message

name: Build
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Check for syntax errors
        run: |
          if ! grep -q "valid" main.js; then
            echo "::error file=main.js,line=5::Syntax error in function"
          fi

2. Creating Warning Annotations

Property Description Example
warning Severity level for the annotation warning
file Path to the file where the warning occurs src/main.js
line Line number in the file where the warning occurs 15
column Column number in the file where the warning occurs 5
message Text of the warning message Use of deprecated function 'oldMethod'

Example: Creating a Warning Annotation

echo "::warning file=src/main.js,line=15,col=5::Use of deprecated function 'oldMethod'"

3. Creating Notice Annotations

Field Description Example
notice.message Required. The message to display in the annotation. Found 10 issues in the code review
notice.title Optional. The title for the annotation. Code Review Issues
notice.file Optional. The path to the file that contains the annotation. src/main.js
notice.line Optional. The line number in the file that contains the annotation. 15
notice.column Optional. The column number in the file that contains the annotation. 5
notice.level Optional. The level of the annotation (notice, warning, error). Default is notice. warning

Example: Creating a Notice Annotation

echo "::notice file=src/main.js,line=15,column=5::Found 10 issues in the code review"
Note: Annotations are only visible in the Actions tab of a workflow run.

4. Setting Annotation File

Property Description Values Notes
annotation-file Path to the annotation file annotations.json File must be in the workflow directory or a subdirectory

Example: Setting Annotation File

name: Annotation Example
on: [push]
jobs:
  annotate:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Set annotation file
        run: |
          echo '{"file": "src/main.js", "line": 10, "message": "This line is problematic"}' > annotations.json

5. Setting Annotation Line

Property Values Description
line number Line number in the file where the annotation should be placed. Must be a positive integer.
endLine number End line number for a multi-line annotation. Must be greater than or equal to line.

Example: Setting Line Numbers in Annotations

name: Annotation Example
on: [push]

jobs:
  annotate:
    runs-on: ubuntu-latest
    steps:
      - name: Annotate Specific Line
        run: |
          echo "::warning file=src/main.js,line=10,endLine=15::This is a multi-line warning"

6. Setting Annotation Column

Property Description Values Notes
annotation.column Specifies the column number in the file where the annotation is placed number Optional. If not provided, the annotation is placed at the beginning of the line

Example: Setting Annotation Column

name: Example Workflow
on: [push]
jobs:
  example-job:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4
      - name: Annotate with Column
        run: |
          echo "::warning file=src/main.js,line=10,column=5::This is a warning with column specified"

7. Setting Annotation Title

Property Values Description
title string The title of the annotation. This is displayed in the GitHub UI.

Example: Setting Annotation Title

name: "Example Workflow"
on:
  push:
    branches: [ main ]

jobs:
  example-job:
    runs-on: ubuntu-latest
    steps:
      - name: "Set Annotation with Title"
        run: |
          echo "::warning title=My Custom Title::This is a warning with a custom title."

8. Using Problem Matchers

Problem matchers are used in GitHub Actions to parse the output of a job and report issues as annotations. They help surface errors, warnings, and other information directly in the GitHub UI.

Field Description Example
owner The owner of the problem matcher "owner": "my-owner"
severity Severity level of the problem (e.g., error, warning) "severity": "error"
message Message to display for the problem "message": "Error in file {0}"
file File path where the problem occurs "file": "{0}"
line Line number in the file where the problem occurs "line": "{1}"
column Column number in the file where the problem occurs "column": "{2}"

Example: Using Problem Matchers in a Workflow

name: Example Workflow with Problem Matchers
on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Run build
        run: |
          echo "Error in file example.js:10"
          echo "Warning in file test.js:5"

      - name: Add problem matcher
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const matcher = {
              owner: "my-owner",
              severity: "error",
              message: "Error in file {0}",
              file: "{0}",
              line: "{1}",
              column: "{2}"
            };
            fs.writeFileSync('.github/problem-matcher.json', JSON.stringify(matcher));
Note: Problem matchers are defined in JSON format and must be placed in the .github directory of your repository.
Warning: Problem matchers are not supported in all GitHub environments. Ensure that your workflow runs in an environment that supports them.

9. Defining Custom Problem Matchers

Problem matchers in GitHub Actions help parse logs and surface issues as annotations in the UI. Custom problem matchers allow you to define your own patterns for detecting specific error or warning messages.

Field Description Example
problemMatcher Defines a custom problem matcher using a JSON object.
{
  "owner": "custom-linter",
  "pattern": [
    {
      "regexp": "^Error: (.+)$",
      "file": 1,
      "line": 2
    }
  ]
}

Example: Defining a Custom Problem Matcher

{
  "owner": "my-linter",
  "pattern": [
    {
      "regexp": "^\\s*(.+):(\\d+):(\\d+):\\s*(error|warning):\\s*(.+)$",
      "file": 1,
      "line": 2,
      "column": 3,
      "severity": 4,
      "message": 5
    }
  ],
  "severity": "error"
}
Note: The owner field is used to group related problems under a single annotation category.
Warning: Problem matchers are processed in order, so more specific patterns should come before general ones to avoid false matches.

10. Registering Problem Matchers

Property Description Example
problemMatcher Defines a problem matcher to parse logs and report issues
[{
  "owner": "mylint",
  "pattern": [{
    "regexp": "Error: (.+)",
    "message": 1
  }],
  "severity": "error"
}]

Example: Registering a Problem Matcher

name: Build
on:
  push:
    branches: [ main ]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Setup problem matcher
        uses: actions/setup-node@v4
        with:
          node-version: '20'
      - name: Run linter
        run: |
          npm install
          npx eslint . --format unix
        env:
          GITHUB_WORKFLOW: ${{ github.workflow }}
          GITHUB_JOB: ${{ github.job }}
Note: Problem matchers help GitHub Actions understand and annotate issues found in logs, improving developer experience by linking errors directly to source code.

11. Removing Problem Matchers

Matcher ID Description Removal Method
problem-matcher-id Identifier for the problem matcher to remove github.actions.removeProblemMatcher('problem-matcher-id')

Example: Removing a Problem Matcher

github.actions.removeProblemMatcher('my-custom-matcher');
Note: The matcher must be previously registered using github.actions.addProblemMatcher.

12. Viewing Annotations

Annotation Type Description Severity Level Example
notice Informational message that does not affect workflow execution notice echo "::notice file=main.js,line=10::This is a notice"
warning Warning that may cause failures or issues warning echo "::warning file=main.js,line=15::Potential issue detected"
error Error that stops workflow execution error echo "::error file=main.js,line=20::Critical error occurred"

Example: Using Annotations in a Workflow

name: Annotation Example
on: [push]

jobs:
  annotate-job:
    runs-on: ubuntu-latest
    steps:
      - name: Check file
        run: |
          echo "::notice file=README.md,line=1::File checked successfully"
          echo "::warning file=README.md,line=5::Missing header"
          echo "::error file=README.md,line=10::Invalid syntax"
Note: Annotations are displayed in the Actions tab of your repository and can be filtered by severity level.

Key Points

  • Annotations provide structured feedback in workflows
  • Three severity levels: notice, warning, error
  • Annotations can include file, line, and column information
  • Errors halt workflow execution; warnings and notices do not

Was this article helpful?