-
-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
48946f4
commit 7c09245
Showing
5 changed files
with
200 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
name: Create GitHub Discussions | ||
|
||
on: | ||
pull_request: | ||
types: [opened] | ||
paths: | ||
- 'src/content/apps/**' | ||
# Allow manual trigger to create discussions for existing apps | ||
workflow_dispatch: | ||
inputs: | ||
createForExisting: | ||
description: 'Create discussions for existing apps' | ||
required: true | ||
default: 'true' | ||
type: boolean | ||
|
||
jobs: | ||
create-discussion: | ||
runs-on: ubuntu-latest | ||
permissions: | ||
discussions: write | ||
pull-requests: read | ||
contents: read | ||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Create Discussion for PR | ||
if: github.event_name == 'pull_request' | ||
uses: actions/github-script@v7 | ||
with: | ||
script: | | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
// Get the changed files from the PR | ||
const { data: files } = await github.rest.pulls.listFiles({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
pull_number: context.issue.number | ||
}); | ||
// Find new app submissions | ||
const appFiles = files.filter(file => | ||
file.status === 'added' && | ||
file.filename.startsWith('src/content/apps/') && | ||
!file.filename.endsWith('_template.md') | ||
); | ||
for (const file of appFiles) { | ||
const content = Buffer.from((await github.rest.repos.getContent({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
path: file.filename, | ||
ref: context.payload.pull_request.head.sha | ||
})).data.content, 'base64').toString(); | ||
await createDiscussion(content); | ||
} | ||
- name: Create Discussions for Existing Apps | ||
if: github.event_name == 'workflow_dispatch' && inputs.createForExisting | ||
uses: actions/github-script@v7 | ||
with: | ||
script: | | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const yaml = require('js-yaml'); | ||
// Get all existing app files | ||
const appsDir = 'src/content/apps'; | ||
const files = fs.readdirSync(appsDir) | ||
.filter(file => file.endsWith('.md') && file !== '_template.md'); | ||
for (const file of files) { | ||
const content = fs.readFileSync(path.join(appsDir, file), 'utf8'); | ||
await createDiscussion(content); | ||
} | ||
async function createDiscussion(content) { | ||
// Parse the frontmatter | ||
const frontmatter = content.split('---')[1]; | ||
const appData = yaml.load(frontmatter); | ||
// Check if discussion already exists | ||
const { data: discussions } = await github.rest.discussions.list({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
category_id: process.env.DISCUSSION_CATEGORY_ID | ||
}); | ||
const existingDiscussion = discussions.find(d => | ||
d.title === `Vote: ${appData.name} by ${appData.author}` | ||
); | ||
if (!existingDiscussion) { | ||
// Create a discussion | ||
await github.rest.discussions.create({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
title: `Vote: ${appData.name} by ${appData.author}`, | ||
body: `🗳️ **Vote for this app by giving it a 👍 reaction!**\n\n${appData.description}`, | ||
category_id: process.env.DISCUSSION_CATEGORY_ID | ||
}); | ||
console.log(`Created discussion for ${appData.name}`); | ||
} else { | ||
console.log(`Discussion already exists for ${appData.name}`); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
name: Update Vote Counts | ||
|
||
on: | ||
schedule: | ||
- cron: '0 */6 * * *' # Run every 6 hours | ||
workflow_dispatch: # Allow manual triggers | ||
|
||
jobs: | ||
update-votes: | ||
runs-on: ubuntu-latest | ||
permissions: | ||
contents: write | ||
discussions: read | ||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Update Vote Counts | ||
uses: actions/github-script@v7 | ||
with: | ||
script: | | ||
const fs = require('fs').promises; | ||
const path = require('path'); | ||
const yaml = require('js-yaml'); | ||
// Get all discussions in the Flutter of the Year category | ||
const discussions = await github.paginate(github.rest.discussions.listForRepo, { | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
category_id: process.env.DISCUSSION_CATEGORY_ID | ||
}); | ||
// Create votes.json with the current vote counts | ||
const votes = {}; | ||
for (const discussion of discussions) { | ||
if (discussion.title.startsWith('Vote: ')) { | ||
const appName = discussion.title.replace('Vote: ', '').split(' by ')[0]; | ||
// Count thumbs up reactions | ||
const reactions = await github.rest.reactions.listForDiscussion({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
discussion_number: discussion.number | ||
}); | ||
votes[appName] = reactions.data.filter(r => r.content === '+1').length; | ||
} | ||
} | ||
// Write the votes to a JSON file | ||
await fs.writeFile( | ||
'src/data/votes.json', | ||
JSON.stringify(votes, null, 2) | ||
); | ||
// Commit and push the changes | ||
const date = new Date().toISOString(); | ||
await exec.exec('git', ['config', 'user.name', 'github-actions[bot]']); | ||
await exec.exec('git', ['config', 'user.email', 'github-actions[bot]@users.noreply.github.com']); | ||
await exec.exec('git', ['add', 'src/data/votes.json']); | ||
await exec.exec('git', ['commit', '-m', `Update vote counts - ${date}`]); | ||
await exec.exec('git', ['push']); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export interface VoteData { | ||
[appName: string]: number; | ||
} | ||
|
||
export function getVotes(): VoteData { | ||
try { | ||
// During build time, this file will be created by GitHub Actions | ||
// We import it as a module to get the data | ||
const votes = import.meta.glob('/src/data/votes.json', { eager: true }); | ||
return Object.values(votes)[0] as VoteData || {}; | ||
} catch (error) { | ||
console.error('Error reading votes:', error); | ||
return {}; | ||
} | ||
} |