Skip to content

Commit 9f33a69

Browse files
init
0 parents  commit 9f33a69

File tree

7 files changed

+746
-0
lines changed

7 files changed

+746
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

Dockerfile

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
FROM node:lts-alpine
2+
3+
# Labels for GitHub to read your action
4+
LABEL "com.github.actions.name"="github-activity-readme"
5+
LABEL "com.github.actions.description"="Updates README with the recent GitHub activity of a user"
6+
7+
RUN apk add --no-cache git
8+
9+
# Copy the package.json and package-lock.json
10+
COPY package*.json ./
11+
12+
# Install dependencies
13+
RUN npm ci
14+
15+
# Copy the rest of your action's code
16+
COPY . .
17+
18+
# Run `node /index.js`
19+
ENTRYPOINT ["node", "/index.js"]

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# GitHub Activity Readme
2+
3+
Updates `README.md` with the recent GitHub activity of a user.

action.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name: GitHub - Activity - Readme
2+
description: Updates README with the recent GitHub activity of a user
3+
author: jamesgeorge007
4+
branding:
5+
color: yellow
6+
icon: activity
7+
runs:
8+
using: docker
9+
image: Dockerfile

index.js

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
require('dotenv').config()
2+
const { spawn } = require('child_process')
3+
const path = require('path')
4+
5+
const fs = require('fs')
6+
7+
const { Toolkit } = require('actions-toolkit')
8+
9+
const MAX_LINES = 5
10+
11+
const capitalize = (str) => str.slice(0, 1).toUpperCase() + str.slice(1)
12+
13+
const urlPrefix = 'https://github.com/'
14+
15+
const toUrlFormat = (item) => {
16+
if (typeof item === 'object') {
17+
return Object.hasOwnProperty.call(item.payload, 'issue')
18+
? `[#${item.payload.issue.number}](${urlPrefix}/${item.repo.name}/issues/${item.payload.issue.number})`
19+
: `[#${item.payload.pull_request.number}](${urlPrefix}/${item.repo.name}/pull/${item.payload.pull_request.number})`
20+
}
21+
return `[${item}](${urlPrefix}/${item})`
22+
}
23+
24+
const exec = (cmd, args = []) =>
25+
new Promise((resolve, reject) => {
26+
console.log(`Started: ${cmd} ${args.join(' ')}`)
27+
const app = spawn(cmd, args, { stdio: 'inherit' })
28+
app.on('close', (code) => {
29+
if (code !== 0) {
30+
err = new Error(`Invalid status code: ${code}`)
31+
err.code = code
32+
return reject(err)
33+
}
34+
return resolve(code)
35+
})
36+
app.on('error', reject)
37+
})
38+
39+
const commitFile = async () => {
40+
await exec('git', [
41+
'config',
42+
'--global',
43+
'user.email',
44+
45+
])
46+
await exec('git', ['config', '--global', 'user.name', 'readme-bot'])
47+
await exec('git', ['add', 'README.md'])
48+
await exec('git', ['commit', '-m', 'update'])
49+
await exec('git', ['push'])
50+
}
51+
52+
const serializers = {
53+
IssueCommentEvent: (item) => {
54+
return `🗣 Commented on ${toUrlFormat(item)} in ${toUrlFormat(
55+
item.repo.name
56+
)}`
57+
},
58+
IssuesEvent: (item) => {
59+
return `❗️ ${capitalize(item.payload.action)} issue ${toUrlFormat(
60+
item
61+
)} in ${toUrlFormat(item.repo.name)}`
62+
},
63+
PullRequestEvent: (item) => {
64+
const emoji = item.payload.action === 'opened' ? '💪' : '❌'
65+
const line = item.payload.pull_request.merged
66+
? '🎉 Merged'
67+
: `${emoji} ${capitalize(item.payload.action)}`
68+
return `${line} PR ${toUrlFormat(item)} in ${toUrlFormat(item.repo.name)}`
69+
},
70+
}
71+
72+
Toolkit.run(
73+
async (tools) => {
74+
const { GH_USERNAME, GH_PAT } = process.env
75+
76+
// Get the user's public events
77+
tools.log.debug(`Getting activity for ${GH_USERNAME}`)
78+
const events = await tools.github.activity.listPublicEventsForUser({
79+
username: GH_USERNAME,
80+
per_page: 100,
81+
})
82+
tools.log.debug(
83+
`Activity for ${GH_USERNAME}, ${events.data.length} events found.`
84+
)
85+
86+
const content = events.data
87+
// Filter out any boring activity
88+
.filter((event) => serializers.hasOwnProperty(event.type))
89+
// We only have five lines to work with
90+
.slice(0, MAX_LINES)
91+
// Call the serializer to construct a string
92+
.map((item) => serializers[item.type](item))
93+
94+
const readmeContent = fs.readFileSync('./README.md', 'utf-8').split('\n')
95+
96+
let startIdx = readmeContent.findIndex(
97+
(content) => content === '<!--START-->'
98+
)
99+
if (
100+
readmeContent.includes('<!--START-->') &&
101+
!readmeContent.includes('<!--END-->')
102+
) {
103+
startIdx++
104+
content.forEach((line, idx) =>
105+
readmeContent.splice(startIdx + idx, 0, `${idx + 1}. ${line}`)
106+
)
107+
readmeContent.splice(startIdx + content.length, 0, '<!--END-->')
108+
fs.writeFileSync('./README.md', readmeContent.join('\n'))
109+
try {
110+
await commitFile()
111+
} catch (err) {
112+
tools.log.debug('Something went wrong')
113+
return tools.exit.failure(err)
114+
}
115+
tools.exit.success('Created initial setup')
116+
}
117+
118+
const endIdx = readmeContent.findIndex(
119+
(content) => content === '<!--END-->'
120+
)
121+
const oldContent = readmeContent.slice(startIdx + 1, endIdx).join('\n')
122+
console.log()
123+
const newContent = content
124+
.map((line, idx) => `${idx + 1}. ${line}`)
125+
.join('\n')
126+
127+
if (oldContent.trim() === newContent.trim())
128+
tools.exit.success('No changes detected')
129+
130+
startIdx++
131+
content.forEach(
132+
(line, idx) => (readmeContent[startIdx + idx] = `${idx + 1}. ${line}`)
133+
)
134+
fs.writeFileSync('./README.md', readmeContent.join('\n'))
135+
try {
136+
await commitFile()
137+
} catch (err) {
138+
tools.log.debug('Something went wrong')
139+
return tools.exit.failure(err)
140+
}
141+
tools.exit.success('Updated ')
142+
},
143+
{
144+
event: 'schedule',
145+
secrets: ['GITHUB_TOKEN', 'GH_PAT', 'GH_USERNAME'],
146+
}
147+
)

0 commit comments

Comments
 (0)