GitHub Actions Tutorial — Non-CI/CD Automation
Non-CI/CD Automation
GitHub Actions isn’t just for CI/CD. It’s a general-purpose automation platform that can automate project management, repository maintenance, and team processes.
Auto-Label Issues
Label new issues based on their content:
name: Label Issues
on:
issues:
types: [opened]
permissions:
issues: write
jobs:
label:
runs-on: ubuntu-latest
steps:
- name: Add labels
uses: actions/github-script@v7
with:
script: |
const title = context.payload.issue.title.toLowerCase();
const body = (context.payload.issue.body || '').toLowerCase();
const labels = [];
if (title.includes('bug') || body.includes('bug')) labels.push('bug');
if (title.includes('feature')) labels.push('enhancement');
if (title.includes('docs')) labels.push('documentation');
if (labels.length > 0) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
labels: labels
});
}
Close Stale Issues
Automatically close issues with no activity:
name: Close Stale Issues
on:
schedule:
- cron: '0 0 * * 1' # every Monday
permissions:
issues: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
stale-issue-message: 'This issue has been inactive for 30 days. It will be closed in 7 days unless there is activity.'
close-issue-message: 'Closed due to inactivity.'
days-before-stale: 30
days-before-close: 7
stale-issue-label: 'stale'
Scheduled Reports
Generate weekly repository metrics:
name: Weekly Report
on:
schedule:
- cron: '0 9 * * 1' # Monday 9am UTC
jobs:
report:
runs-on: ubuntu-latest
steps:
- name: Generate report
uses: actions/github-script@v7
with:
script: |
const oneWeekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString();
const { data: issues } = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'all',
since: oneWeekAgo
});
const opened = issues.filter(i => !i.pull_request && new Date(i.created_at) > new Date(oneWeekAgo));
const closed = issues.filter(i => !i.pull_request && i.state === 'closed');
const body = `## Weekly Report\n\n- Issues opened: ${opened.length}\n- Issues closed: ${closed.length}`;
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `Weekly Report - ${new Date().toISOString().split('T')[0]}`,
body: body,
labels: ['report']
});
Welcome New Contributors
name: Welcome
on:
pull_request_target:
types: [opened]
permissions:
pull-requests: write
jobs:
welcome:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
with:
script: |
const creator = context.payload.pull_request.user.login;
const { data: prs } = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'all',
creator: creator
});
if (prs.length === 1) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: `Welcome @${creator}! 🎉 Thanks for your first PR!`
});
}
Quick Reference
| Automation | Trigger |
|---|---|
| Label issues | issues: opened |
| Close stale | schedule (weekly) |
| Weekly reports | schedule (cron) |
| Welcome PRs | pull_request_target: opened |
| Sync files | push to a central repo |
← Previous: GitHub Apps
Next: Community Resources →