GitHub Automation: From Actions to an Engineering-Ops Agent
GitHub Actions is right for CI. Cross-system engineering operations need a predictable agent that connects GitHub, Linear, and Slack, then runs repeatable triage as a governed app.

What GitHub automation is (and where YAML stops)
GitHub automation covers four surfaces, and most teams only use the first. GitHub Actions runs workflow YAML on events like push, pull_request, and schedule, executing jobs on runners in a graph you define ahead of time. Webhooks push event payloads to a URL you control. The REST API reads and writes pulls, issues, reviews, releases, and checks. GitHub Apps tie the last two together with an installable identity and scoped permissions.
Actions is the right tool for build, test, and deploy. It lives next to the code, and GitHub ships an Actions Importer that converts pipelines from Jenkins, CircleCI, GitLab, Azure DevOps, and others into workflow files. If your problem is "run these steps on every commit," write the YAML and stop reading.
YAML stops where the decision needs context from outside the repo. A workflow can fail a build. It has no good way to read the Linear cycle the PR belongs to, notice that the same service has an open incident thread in Slack, and decide that this change should wait for the on-call engineer. Teams that try end up with thousand-line workflow files and a bot token nobody wants to audit.
That gap is where an engineering-ops agent earns its keep. An agent reasons across GitHub, Linear, and Slack, keeps state between runs, and asks a human before anything consequential happens.
| Approach | Scope | Cross-system reasoning | Persistent state | Human approval | |---|---|---|---|---| | Major engineering-ops agent | GitHub plus Linear, Slack, and internal systems | Yes, the agent weighs context from every connected system | Managed database, storage, and audit log in the app it builds | Built in, as a Slack or in-app gate before any write | | GitHub Actions | One repository's build, test, and deploy graph | None beyond what a step script fetches | Artifacts and caches scoped to runs | Environment protection rules on deploy jobs | | Rule-based webhook glue | Event-to-action mappings | None, rules fire on field matches | Usually none beyond run history | Rarely, and bolted on |
When an AI agent over GitHub actually helps
Four patterns justify an agent. Everything else is still an Actions job.
PR review with Linear and Slack context
The PR Context Agent fires on pull_request with action opened or synchronize. It pulls the diff, the check runs, and the linked Linear issue, then posts a short brief in Slack: what changed, which acceptance criteria it touches, which checks failed and whether they failed on main too. It suggests reviewers from CODEOWNERS and recent file history.
The hard part is linking. Branch names and PR titles are inconsistent, so the agent has to match Linear issues by key, by title similarity, and by author, then say how confident it is. A wrong link is worse than no link.
Release management and human publication
The Release Drafter Agent watches merged PRs since the last tag, groups them by Linear project, and writes release notes a human would actually read. It creates the release through the API with draft: true. A person reviews and clicks publish. The release webhook with action published then triggers the Actions deploy you already have.
This is the pattern where people get tempted to skip the gate. Don't. A published release is a public, often irreversible artifact.
Security-alert triage
The Alert Triage Agent listens for dependabot_alert events. It checks whether the vulnerable package is reachable from production code, whether a fix PR already exists, and which Linear team owns the service. Low-severity dev dependencies get batched into a weekly issue. A critical, reachable alert gets a Linear ticket assigned to the owning team and a Slack page to their channel.
It can go wrong on reachability. Static import analysis is a heuristic, so the agent should present its reasoning and let the owner overrule it, with the override stored for next time.
Issue summarization and CI orchestration
The agent summarizes a 90-comment issue into current state and open questions, or watches workflow_run completions to spot a test that fails intermittently across branches and files one issue instead of forty. It can call workflow_dispatch to rerun a job, which is safe. It should never edit workflow files on its own.
What you need to build one
GitHub REST API: auth, pulls, reviews, issues, releases, checks, and webhooks
Authenticate as a GitHub App. You register the app, install it on an org or selected repos, sign a JWT with the app's private key, and exchange it for a short-lived installation token. The endpoints the patterns above use:
GET /repos/{owner}/{repo}/pulls/{pull_number}and/pulls/{pull_number}/filesfor the PR and diffGET /repos/{owner}/{repo}/commits/{ref}/check-runsfor CI statusPOST /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewersand/pulls/{pull_number}/reviewsPOST /repos/{owner}/{repo}/issues/{issue_number}/commentsfor PR and issue commentsPOST /repos/{owner}/{repo}/releaseswithdraft: trueGET /repos/{owner}/{repo}/dependabot/alerts
Webhook events to subscribe to: pull_request, pull_request_review, check_suite, workflow_run, release, dependabot_alert, and issues. Verify every payload against the X-Hub-Signature-256 header before acting on it.
Pros and cons: Apps, PATs, delivery retries, and rate limits
Apps beat personal access tokens for this work. An App has its own identity in the audit log, permissions scoped per repository, and its own rate-limit pool. A PAT acts as a person, and the rate-limit docs note that PAT requests share one budget with any app acting on that user's behalf. Writing check runs is also App-only.
The permission split is the useful gotcha. Requesting reviewers and posting PR comments need Pull requests write. Merging a PR through the API needs Contents write. Grant the first and withhold the second, and the agent structurally cannot merge, whatever its prompt says.
Two operational cons. GitHub does not automatically redeliver failed webhooks, so a receiver that is down or slow to respond simply misses events. You need a scheduled job that lists recent deliveries and redelivers failures. And secondary rate limits exist, are not fully published, and can change without notice. Read the x-ratelimit-remaining and retry-after headers, back off exponentially, and don't hardcode a request budget.
Connector catalogs like the Pipedream GitHub app list the same surface as triggers, such as New or Updated Pull Request and New Security Alert. That is event wiring. The judgment and the state are still yours to build.
A worked example: the PR-triage agent
Here is the flow end to end. The shape carries over to other agents across operational systems.
- A
pull_requestwebhook arrives with actionopenedorsynchronize, or adependabot_alertarrives with actioncreated. The app verifies the signature and writes an event row keyed on theX-GitHub-DeliveryID, so a redelivered event is ignored. - The app fetches the PR, changed files, and check runs through the installation token.
- The agent searches Linear for the matching issue and reads its status, cycle, and team.
- The agent decides. Ready for review, blocked on failing checks, missing a linked issue, or escalate.
- The app posts a Slack message to the team channel with the summary and Approve / Escalate buttons.
- On Approve, the app requests the suggested reviewers and posts one PR comment. On Escalate, it assigns the Linear issue to the owner and notifies the channel.
- Every decision, approver, and API call lands in the app's audit table.
Step 2 is plain HTTP:
curl -s \ -H "Authorization: Bearer $INSTALLATION_TOKEN" \ -H "Accept: application/vnd.github+json" \ -H "X-GitHub-Api-Version: 2022-11-28" \ "https://api.github.com/repos/acme/payments-api/commits/$HEAD_SHA/check-runs"
And step 6, after a human clicks Approve:
curl -s -X POST \ -H "Authorization: Bearer $INSTALLATION_TOKEN" \ -H "Accept: application/vnd.github+json" \ -H "X-GitHub-Api-Version: 2022-11-28" \ "https://api.github.com/repos/acme/payments-api/pulls/412/requested_reviewers" \ -d '{"reviewers":["dana-kim"],"team_reviewers":["payments-core"]}'
The App holds read on contents and checks, write on pull requests and issues, and nothing else. A human approves every merge and every release. The agent never touches the merge button because its credentials cannot reach it.
Notice how little of this needs a model. Steps 1, 2, 5, 6, and 7 are deterministic code. Only the Linear match and the decision in step 4 need judgment. The same split shows up in Salesforce agents and spreadsheet automation, and it is why routing each step to the right model, or to no model at all, matters.
Build this in Major
The constraint with every GitHub bot is the same. The moment it reasons across Linear and Slack, it becomes a black box holding repo credentials, and its memory of what it decided last week lives in a context window that is gone.
Major is the enterprise platform where agents build the software they run on. The PR-triage agent works out the flow once, then builds it as an app. Webhook verification, delivery dedupe, the check-run fetch, the Slack approval, and the audit table run as deterministic code with a managed database behind them. The agent is called only for the Linear match and the triage call. Reason once. Run forever. Your team's CODEOWNERS overrides, past escalations, and reviewer load all persist in the app, so the fiftieth PR is triaged with more context than the first, and model spend stays front-loaded instead of climbing with PR volume.
If all you need is CI, Actions is enough and you should keep it. Major earns its place when the work spans GitHub, Linear, and Slack and someone in security wants to know exactly what the bot did. The GitHub App's scopes sit behind Major's credential proxy, every action is attributed in the audit log, and the same app is the control surface your engineering managers use to see the queue.
Start with the PR-triage flow above: one repo, read plus comment scopes, Slack approval on every write. Get started on Major and build your GitHub PR-triage agent.
Related articles
Frequently asked questions
- What is GitHub automation?
- GitHub automation is any work GitHub performs without a person clicking. GitHub Actions runs workflow YAML for build, test, and deploy. Webhooks send events to external services, the REST API reads and writes repository data, and GitHub Apps provide scoped identities. An engineering-ops agent adds judgment across GitHub, Linear, and Slack, with human approval on consequential writes.
- Is GitHub Actions like Jenkins?
- Yes, in category. Both are CI/CD systems that run pipelines of jobs when code changes. Jenkins is usually self-hosted and extended with plugins. Actions runs workflow YAML stored in the repository on GitHub-hosted or self-hosted runners. GitHub's Actions Importer converts Jenkins pipelines into Actions workflows, and GitHub advises reviewing converted workflows before production use.
- Is GitHub still owned by Microsoft?
- Yes. Microsoft completed its acquisition of GitHub on October 26, 2018, according to Microsoft's official announcement. At the time, Microsoft said GitHub would keep its developer-first approach, operate independently, and remain an open platform.
- What is replacing GitHub?
- This article does not recommend replacing GitHub. It remains the system of record for code, pull requests, and CI through Actions. The gap teams feel is governed cross-system operations: triage that reads Linear and Slack, keeps state between runs, and asks a human before any write. That layer sits beside GitHub, built as apps an agent runs.