---
title: GitHub CI
description: Mount GitHub Actions workflows, runs, jobs, logs, and artifacts as a read-only Mirage filesystem.
icon: circle-play
---
The GitHub CI resource mounts GitHub Actions workflows and runs as a
read-only virtual filesystem.

For token setup, see [GitHub CI Setup](/python/setup/github_ci).

## Config

```python
import os

from mirage import MountMode, Workspace
from mirage.resource.github_ci import GitHubCIConfig, GitHubCIResource

config = GitHubCIConfig(
    token=os.environ["GITHUB_TOKEN"],
    owner="my-org",
    repo="my-repo",
)
resource = GitHubCIResource(config=config)
ws = Workspace({"/ci": resource}, mode=MountMode.READ)
```

## Filesystem Layout

```text
/ci/
  workflows/
    <workflow-name>_<workflow-id>.json
  runs/
    <workflow-name>_<run-id>/
      run.json
      jobs/
        <job-name>_<job-id>.json
        <job-name>_<job-id>.log
      annotations.jsonl
      artifacts/
        <artifact-name>_<artifact-id>.zip
```

Example:

```text
/ci/
  workflows/
    CI_12345678.json
    Deploy_87654321.json
  runs/
    CI_9876543210/
      run.json
      jobs/
        build_11111111.json
        build_11111111.log
        test_22222222.json
        test_22222222.log
      annotations.jsonl
      artifacts/
        coverage-report_55555.zip
```

### Workflows

`/ci/workflows/` lists all workflows defined in the repository.
Each `.json` file contains the workflow metadata (name, path, state).

### Runs

`/ci/runs/` lists recent workflow runs within the configured time window
(default 30 days). The `created` API parameter filters server-side.

Each run directory contains:

- `run.json` - run metadata (status, conclusion, event, branch, actor, timing)
- `jobs/` - one `.json` and `.log` pair per job
- `annotations.jsonl` - check annotations (warnings, errors) across all jobs
- `artifacts/` - downloadable build artifacts

### Jobs

Each job has two files:

- `<job-name>_<job-id>.json` - job metadata with steps and timing
- `<job-name>_<job-id>.log` - full job log (plain text)

### Artifacts

Artifacts are served as `.zip` files matching the GitHub API download format.

## Cache

The GitHub CI resource uses `IndexCacheStore` with `remote_time`-based
fingerprinting. Completed runs and jobs are effectively immutable and
benefit from long cache TTL.

## Example

```python
import asyncio
import os

from dotenv import load_dotenv

from mirage import MountMode, Workspace
from mirage.resource.github_ci import GitHubCIConfig, GitHubCIResource

load_dotenv(".env.development")


async def main():
    config = GitHubCIConfig(
        token=os.environ["GITHUB_TOKEN"],
        owner="my-org",
        repo="my-repo",
    )
    resource = GitHubCIResource(config=config)
    ws = Workspace({"/ci": resource}, mode=MountMode.READ)

    # List top-level
    r = await ws.execute("ls /ci/")
    print(await r.stdout_str())

    # List workflows
    r = await ws.execute("ls /ci/workflows/")
    print(await r.stdout_str())

    # List recent runs
    r = await ws.execute("ls /ci/runs/")
    print(await r.stdout_str())

    # Read run metadata
    r = await ws.execute("cat /ci/runs/CI_9876543210/run.json")
    print(await r.stdout_str())

    # List jobs for a run
    r = await ws.execute("ls /ci/runs/CI_9876543210/jobs/")
    print(await r.stdout_str())

    # Read job log
    r = await ws.execute("cat /ci/runs/CI_9876543210/jobs/build_11111111.log")
    print(await r.stdout_str())

    # Read annotations
    r = await ws.execute("cat /ci/runs/CI_9876543210/annotations.jsonl")
    print(await r.stdout_str())

    # Tree view
    r = await ws.execute("tree -L 2 /ci/")
    print(await r.stdout_str())

    # Find all failed job logs
    r = await ws.execute("find /ci/runs/ -name '*.log'")
    print(await r.stdout_str())


if __name__ == "__main__":
    asyncio.run(main())
```

## Shell Commands

Standard commands available on the mounted GitHub CI tree:

| Command         | Notes                          |
| --------------- | ------------------------------ |
| `ls`            | List workflows, runs, jobs     |
| `cat`           | Read JSON metadata or job logs |
| `head` / `tail` | First/last N lines             |
| `wc`            | Line/word/byte counts          |
| `stat`          | File metadata (type, IDs)      |
| `find`          | Recursive search with `-name`  |
| `tree`          | Directory tree view            |

## Working with CI Data

```bash
# Check run status via jq
cat /ci/runs/CI_9876543210/run.json | jq '.conclusion'

# List all job names
ls /ci/runs/CI_9876543210/jobs/ | grep '.json$'

# Tail a job log for recent output
tail -n 50 /ci/runs/CI_9876543210/jobs/build_11111111.log

# Count annotations
wc -l /ci/runs/CI_9876543210/annotations.jsonl

# Find all .log files
find /ci/ -name "*.log"
```
