Skip to content

Commit 406ed85

Browse files
Merge pull request #9 from Siddhant-K-code/main
Add sponsorship data integration with README
2 parents df9c3d2 + 5c3bb02 commit 406ed85

File tree

6 files changed

+176
-42
lines changed

6 files changed

+176
-42
lines changed

README.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,33 @@ jobs:
2929
runs-on: ubuntu-latest
3030
steps:
3131
- name: Checkout repository
32-
uses: actions/checkout@v2
32+
uses: actions/checkout@v4
3333

3434
- name: Fetch Sponsorships and Commit
35-
uses: @santoshyadavdev/sponsoship-green-squares@master
35+
uses: santoshyadavdev/sponsorship-green-squares@main
36+
with:
37+
allow-add-to-readme: 'false' # Default value, set to 'true' to enable README updates
3638
env:
3739
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40+
```
41+
42+
### Readme Integration
43+
44+
When `allow-add-to-readme` is set to 'true', the action will update your
45+
README.md with sponsorship data. Add these markers where you want the data to
46+
appear:
3847

48+
```markdown
49+
<!-- SPONSORSHIP-DATA:START -->
50+
<!-- SPONSORSHIP-DATA:END -->
3951
```
4052

53+
The action will automatically insert sponsorship data between these markers in
54+
the format:
55+
56+
- @username: 5 USD
57+
- @sponsor2: 10 USD
58+
4159
### Inputs
4260

4361
GH_USERNAME: Your GitHub username (default: ${{ github.repository_owner }})

action.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ inputs:
2323
description: 'Email of the committer'
2424
default: 'github-actions[bot]@users.noreply.github.com'
2525
required: false
26+
allow-add-to-readme:
27+
description: 'Add sponsorship data to README.md'
28+
required: false
29+
default: 'false'
2630

2731
runs:
2832
using: node20

dist/index.js

Lines changed: 73 additions & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main.ts

Lines changed: 76 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as core from '@actions/core'
33
import { graphql } from '@octokit/graphql'
44
import { execSync } from 'child_process'
55
import { Octokit } from '@octokit/rest'
6+
import * as fs from 'fs'
67

78
// Get config
89
const GH_USERNAME = core.getInput('GH_USERNAME')
@@ -66,7 +67,10 @@ async function fetchSponsoredProfiles(): Promise<SponsoredProfile[]> {
6667
}
6768
}
6869

69-
async function commitIfNotDuplicate(commitMessage: string) {
70+
async function commitIfNotDuplicate(
71+
commitMessage: string,
72+
fileUpdate?: { path: string; content: string }
73+
): Promise<void> {
7074
const { data: commits } = await octokit.repos.listCommits({
7175
owner: GH_USERNAME,
7276
repo: GH_USERNAME,
@@ -78,42 +82,97 @@ async function commitIfNotDuplicate(commitMessage: string) {
7882
)
7983

8084
if (!duplicateCommit) {
81-
// Commit the changes
85+
if (fileUpdate) {
86+
fs.writeFileSync(fileUpdate.path, fileUpdate.content, 'utf8')
87+
execSync(`git add ${fileUpdate.path}`)
88+
}
8289
execSync(`git config --global user.name "${COMMIT_NAME}"`)
8390
execSync(`git config --global user.email "${COMMIT_EMAIL}"`)
8491
execSync(`git commit --allow-empty -m "${commitMessage}"`)
8592
execSync('git push')
8693
} else {
87-
core.setFailed(`Duplicate commit found: ${commitMessage}`)
94+
core.info(`Skipping duplicate commit: ${commitMessage}`)
8895
}
8996
}
9097

98+
async function updateReadme(profiles: SponsoredProfile[]): Promise<void> {
99+
const allowReadmeUpdate = core.getInput('allow-add-to-readme') === 'true'
100+
if (!allowReadmeUpdate) return
101+
102+
if (!Array.isArray(profiles)) {
103+
throw new Error('Invalid profiles data')
104+
}
105+
106+
const readmePath = 'README.md'
107+
const startMarker = '<!-- SPONSORSHIP-DATA:START -->'
108+
const endMarker = '<!-- SPONSORSHIP-DATA:END -->'
109+
110+
let readmeContent = ''
111+
try {
112+
readmeContent = fs.readFileSync(readmePath, 'utf8')
113+
} catch (error) {
114+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
115+
core.warning('README.md not found, creating new file')
116+
} else {
117+
throw new Error(`Failed to read README.md: ${error}`)
118+
}
119+
}
120+
121+
const sponsorshipData = profiles
122+
.map((p) => `- @${p.sponsorLogin}: ${p.sponsorshipAmount} ${p.currency}`)
123+
.join('\n')
124+
125+
const newContent = `${startMarker}\n${sponsorshipData}\n${endMarker}`
126+
127+
if (readmeContent) {
128+
const startIndex = readmeContent.indexOf(startMarker)
129+
const endIndex = readmeContent.indexOf(endMarker) + endMarker.length
130+
131+
if (startIndex === -1 || endIndex === -1) {
132+
core.info('Markers not found, appending content to README')
133+
readmeContent = `${readmeContent}\n\n${newContent}`
134+
} else if (endIndex <= startIndex) {
135+
throw new Error('Invalid marker positions in README.md')
136+
} else {
137+
readmeContent =
138+
readmeContent.substring(0, startIndex) +
139+
newContent +
140+
readmeContent.substring(endIndex)
141+
}
142+
} else {
143+
readmeContent = newContent
144+
}
145+
146+
await commitIfNotDuplicate(`Update README with sponsorship data`, {
147+
path: readmePath,
148+
content: readmeContent
149+
})
150+
}
151+
91152
/**
92153
* The main function for the action.
93154
*
94155
* @returns Resolves when the action is complete.
95156
*/
157+
96158
export async function run(): Promise<void> {
97159
try {
98160
const ms: string = core.getInput('milliseconds')
161+
const profiles = await fetchSponsoredProfiles()
162+
await updateReadme(profiles)
99163

100-
// Debug logs are only output if the `ACTIONS_STEP_DEBUG` secret is true
101164
core.debug(`Waiting ${ms} milliseconds ...`)
165+
core.debug(`number of profiles fetched: ${profiles.length}`)
102166

103-
// Log the current timestamp, wait, then log the new timestamp
104-
fetchSponsoredProfiles().then((data) => {
105-
core.debug(`number of profiles fetched: ${data.length}`)
106-
const currentDate = new Date()
107-
const month = currentDate.toLocaleString('default', { month: 'long' })
108-
const year = currentDate.getFullYear()
167+
const currentDate = new Date()
168+
const month = currentDate.toLocaleString('default', { month: 'long' })
169+
const year = currentDate.getFullYear()
109170

110-
data.forEach(async (profile) => {
111-
core.debug(`Sponsor: ${profile.sponsorLogin}`)
112-
const commitMessage = `${profile.sponsorshipAmount} ${profile.currency} paid to @${profile.sponsorLogin} for ${month} ${year} to support open source.`
113-
114-
await commitIfNotDuplicate(commitMessage)
115-
})
116-
})
171+
for (const profile of profiles) {
172+
core.debug(`Sponsor: ${profile.sponsorLogin}`)
173+
const commitMessage = `${profile.sponsorshipAmount} ${profile.currency} paid to @${profile.sponsorLogin} for ${month} ${year} to support open source.`
174+
await commitIfNotDuplicate(commitMessage)
175+
}
117176
} catch (error) {
118177
// Fail the workflow run if an error occurs
119178
if (error instanceof Error) core.setFailed(error.message)

0 commit comments

Comments
 (0)