├── .gitignore
├── .github
├── ISSUE_TEMPLATE
│ ├── config.yml
│ ├── 4-bug.yml
│ ├── 5-feature.yml
│ ├── 3-category.yml
│ ├── 1-repository.yml
│ └── 2-change.yml
├── pull_request_template.md
├── dependabot.yml
└── workflows
│ ├── dependabot.yml
│ ├── reference.yml
│ ├── issue.yml
│ ├── accepted.yml
│ ├── category.yml
│ ├── repository.yml
│ ├── change.yml
│ └── update.yml
├── logo.png
├── categories.json
├── repositories.json
├── README.md
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Katsute/awesome-myanimelist/HEAD/logo.png
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/categories.json:
--------------------------------------------------------------------------------
1 | [
2 | "Android",
3 | "Browser Extension",
4 | "Client",
5 | "Database",
6 | "Discord Bot",
7 | "List Design",
8 | "List Tracker",
9 | "Profile",
10 | "Programming",
11 | "Userscript",
12 | "Website"
13 | ]
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: github-actions
4 | directory: /
5 | labels: [dependencies]
6 | assignees: [Katsute]
7 | schedule:
8 | interval: monthly
9 | time: "00:00"
10 | timezone: US/Eastern
11 | open-pull-requests-limit: 10
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/4-bug.yml:
--------------------------------------------------------------------------------
1 | name: ⚠️ Bug Report
2 | description: Report an issue with this repository.
3 | labels: [bug]
4 | body:
5 | - type: textarea
6 | attributes:
7 | label: Issue
8 | description: |
9 | Describe the issue and include steps to replicate if possible.
10 | validations:
11 | required: true
--------------------------------------------------------------------------------
/.github/workflows/dependabot.yml:
--------------------------------------------------------------------------------
1 | name: Dependabot[bot]
2 |
3 | on: [pull_request_target]
4 |
5 | jobs:
6 | dependabot:
7 | name: Dependabot[bot]
8 | runs-on: ubuntu-latest
9 | timeout-minutes: 10
10 | if: github.event.pull_request.user.login == 'dependabot[bot]'
11 | steps:
12 | - name: Checkout Repository
13 | uses: actions/checkout@v6
14 |
15 | - name: Approve Pull Request
16 | continue-on-error: true
17 | run: gh pr review $PR --approve
18 | env:
19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
20 | PR: ${{ github.event.pull_request.number }}
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/5-feature.yml:
--------------------------------------------------------------------------------
1 | name: 🆕 Feature Request
2 | description: Suggestions for this repository.
3 | labels: [feature request]
4 | body:
5 | - type: markdown
6 | attributes:
7 | value: |
8 | This form is only for requesting new features, if you want to add a new category or repository please use one of the below forms:
9 |
10 | * [Category Request](https://github.com/Katsute/awesome-myanimelist/issues/new?template=3-category.yml)
11 | * [Repository Request](https://github.com/Katsute/awesome-myanimelist/issues/new?template=1-repository.yml)
12 |
13 | - type: textarea
14 | attributes:
15 | label: Feature
16 | description: |
17 | Describe the feature.
18 | validations:
19 | required: true
20 |
21 | - type: textarea
22 | attributes:
23 | label: Reason
24 | description: |
25 | Explain why this feature should be added.
26 | validations:
27 | required: true
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/3-category.yml:
--------------------------------------------------------------------------------
1 | name: ➕ Category Request
2 | description: Add a new category type to this list.
3 | labels: [category request]
4 | assignees: [Katsute]
5 | body:
6 | - type: input
7 | attributes:
8 | label: Category
9 | description: The proposed category name. Alphanumerics only.
10 | validations:
11 | required: true
12 |
13 | - type: textarea
14 | attributes:
15 | label: Reason
16 | description: Explain why you think this category should be added.
17 | validations:
18 | required: true
19 |
20 | - type: textarea
21 | attributes:
22 | label: Examples
23 | description: Include a list of repositories that might appear in the proposed category (using ones already in this list is also acceptable).
24 | validations:
25 | required: true
26 |
27 | - type: markdown
28 | attributes:
29 | value: |
30 | Do not modify this form after you submit your request, our workflows depend on a strict request format.
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/1-repository.yml:
--------------------------------------------------------------------------------
1 | name: ➕ Repository Request
2 | description: Add your repository to this list.
3 | labels: [repository request]
4 | assignees: [Katsute]
5 | body:
6 | - type: markdown
7 | attributes:
8 | value: |
9 | Repositories can only be submitted to this list if:
10 |
11 | * Related directly to MyAnimeList.
12 | * At least 10 stars.
13 | * Updated within the last year.
14 |
15 | - type: input
16 | attributes:
17 | label: Repository
18 | description: |
19 | The repository owner and name. Example: `Katsute/awesome-myanimelist`
20 | validations:
21 | required: true
22 |
23 | - type: dropdown
24 | attributes:
25 | label: Category
26 | description: Which categories the repository should appear in.
27 | multiple: true
28 | options: [Android, Browser Extension, Client, Database, Discord Bot, List Design, List Tracker, Profile, Programming, Userscript, Website]
29 | validations:
30 | required: true
31 |
32 | - type: markdown
33 | attributes:
34 | value: |
35 | Do not modify this form after you submit your request, our workflows depend on a strict request format.
--------------------------------------------------------------------------------
/.github/workflows/reference.yml:
--------------------------------------------------------------------------------
1 | name: Repository Reference
2 |
3 | on:
4 | issues:
5 | types: [opened, reopened]
6 |
7 | jobs:
8 | lock-issue:
9 | name: Repository Reference
10 | runs-on: ubuntu-latest
11 | if: contains(github.event.issue.labels.*.name, 'repository request') || contains(github.event.issue.labels.*.name, 'change request')
12 | steps:
13 | - name: Checkout Repository
14 | uses: actions/checkout@v6
15 | with:
16 | token: ${{ secrets.GITHUB_TOKEN }}
17 |
18 | - name: Parse Body
19 | uses: actions/github-script@v8
20 | env:
21 | BODY: ${{ github.event.issue.body }}
22 | with:
23 | github-token: ${{ secrets.GITHUB_TOKEN }}
24 | script: |-
25 | core.exportVariable("REPOSITORY", process.env.BODY.split(/(?:\r?\n){2,}/gm)[1]);
26 |
27 | - name: Post Comment
28 | run: |-
29 | gh issue comment $ISSUE -b "Repository: [$REPOSITORY](https://github.com/$REPOSITORY)
This is an automated message, do not reply to this comment."
30 | env:
31 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32 | ISSUE: ${{ github.event.issue.number }}
33 | REPOSITORY: ${{ env.REPOSITORY }}
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/2-change.yml:
--------------------------------------------------------------------------------
1 | name: ➕ Change Request
2 | description: Change or remove a listed repository.
3 | labels: [change request]
4 | assignees: [Katsute]
5 | body:
6 | - type: markdown
7 | attributes:
8 | value: |
9 | Change requests are only permitted if you **own the repository** that is being changed. Do not submit a request if you are not the owner.
10 |
11 | - type: input
12 | attributes:
13 | label: Repository
14 | description: |
15 | The repository owner and name. Example: `Katsute/awesome-myanimelist`
16 | validations:
17 | required: true
18 |
19 | - type: dropdown
20 | attributes:
21 | label: Change Request
22 | options:
23 | - Modify this listing
24 | - Remove this listing
25 | validations:
26 | required: true
27 |
28 | - type: markdown
29 | attributes:
30 | value: |
31 | If you are removing a listing you can skip the below section, otherwise please select which categories the repository should be listed under.
32 |
33 | - type: dropdown
34 | attributes:
35 | label: Category
36 | description: Which categories the repository should appear in.
37 | multiple: true
38 | options: [Android, Browser Extension, Client, Database, Discord Bot, List Design, List Tracker, Profile, Programming, Userscript, Website]
39 | validations:
40 | required: false
41 |
42 | - type: markdown
43 | attributes:
44 | value: |
45 | Do not modify this form after you submit your request, our workflows depend on a strict request format.
--------------------------------------------------------------------------------
/.github/workflows/issue.yml:
--------------------------------------------------------------------------------
1 | name: Issue Lock
2 |
3 | on:
4 | issues:
5 | types: [opened, reopened, closed]
6 | pull_request:
7 | types: [opened, reopened, closed]
8 |
9 | jobs:
10 | lock-issue:
11 | name: Lock Issue
12 | runs-on: ubuntu-latest
13 | if: github.event.action == 'closed' && github.event.issue
14 | steps:
15 | - name: Checkout Repository
16 | uses: actions/checkout@v6
17 | with:
18 | token: ${{ secrets.GITHUB_TOKEN }}
19 |
20 | - name: Lock Issue
21 | run: gh issue lock $ISSUE
22 | env:
23 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
24 | ISSUE: ${{ github.event.issue.number }}
25 |
26 | unlock-issue:
27 | name: Unlock Issue
28 | runs-on: ubuntu-latest
29 | if: github.event.action != 'closed' && github.event.issue
30 | steps:
31 | - name: Checkout Repository
32 | uses: actions/checkout@v6
33 | with:
34 | token: ${{ secrets.GITHUB_TOKEN }}
35 |
36 | - name: Unlock Issue
37 | run: gh issue unlock $ISSUE
38 | env:
39 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40 | ISSUE: ${{ github.event.issue.number }}
41 |
42 | lock-pr:
43 | name: Lock Pull Request
44 | runs-on: ubuntu-latest
45 | if: github.event.action == 'closed' && github.event.pull_request
46 | steps:
47 | - name: Checkout Repository
48 | uses: actions/checkout@v6
49 | with:
50 | token: ${{ secrets.GITHUB_TOKEN }}
51 |
52 | - name: Lock Issue
53 | run: gh pr lock $ISSUE
54 | env:
55 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
56 | ISSUE: ${{ github.event.pull_request.number }}
57 |
58 | unlock-pr:
59 | name: Unlock Pull Request
60 | runs-on: ubuntu-latest
61 | if: github.event.action != 'closed' && github.event.pull_request
62 | steps:
63 | - name: Checkout Repository
64 | uses: actions/checkout@v6
65 | with:
66 | token: ${{ secrets.GITHUB_TOKEN }}
67 |
68 | - name: Unlock Issue
69 | run: gh pr unlock $ISSUE
70 | env:
71 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
72 | ISSUE: ${{ github.event.pull_request.number }}
--------------------------------------------------------------------------------
/repositories.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "repository": "9elt/Reko",
4 | "category": [
5 | "Website"
6 | ]
7 | },
8 | {
9 | "repository": "axiel7/MoeList",
10 | "category": [
11 | "Android",
12 | "List Tracker"
13 | ]
14 | },
15 | {
16 | "repository": "Chris-Kode/myanimelist-api-v2",
17 | "category": [
18 | "Programming"
19 | ]
20 | },
21 | {
22 | "repository": "darenliang/mal-api",
23 | "category": [
24 | "Programming"
25 | ]
26 | },
27 | {
28 | "repository": "destructo570/Sushi-Unofficial-MAL-Client",
29 | "category": [
30 | "Android",
31 | "List Tracker"
32 | ]
33 | },
34 | {
35 | "repository": "Drutol/MALClient",
36 | "category": [
37 | "Android",
38 | "Client",
39 | "List Tracker"
40 | ]
41 | },
42 | {
43 | "repository": "erengy/taiga",
44 | "category": [
45 | "Client",
46 | "List Tracker"
47 | ]
48 | },
49 | {
50 | "repository": "infanf/myanili",
51 | "category": [
52 | "List Tracker",
53 | "Website"
54 | ]
55 | },
56 | {
57 | "repository": "JICA98/DailyAL",
58 | "category": [
59 | "Client"
60 | ]
61 | },
62 | {
63 | "repository": "jikan-me/jikan",
64 | "category": [
65 | "Programming"
66 | ]
67 | },
68 | {
69 | "repository": "KatsuteDev/Mal4J",
70 | "category": [
71 | "Programming"
72 | ]
73 | },
74 | {
75 | "repository": "Kylart/MalScraper",
76 | "category": [
77 | "Programming"
78 | ]
79 | },
80 | {
81 | "repository": "MAL-Dubs/MAL-Dubs",
82 | "category": [
83 | "Userscript"
84 | ]
85 | },
86 | {
87 | "repository": "MALSync/MALSync",
88 | "category": [
89 | "Browser Extension",
90 | "List Tracker"
91 | ]
92 | },
93 | {
94 | "repository": "nstratos/go-myanimelist",
95 | "category": [
96 | "Programming"
97 | ]
98 | },
99 | {
100 | "repository": "platers/MAL-Map",
101 | "category": [
102 | "Programming"
103 | ]
104 | },
105 | {
106 | "repository": "rl404/sekai",
107 | "category": [
108 | "Website"
109 | ]
110 | },
111 | {
112 | "repository": "Sharkaboi/MediaHub",
113 | "category": [
114 | "Android",
115 | "List Tracker"
116 | ]
117 | },
118 | {
119 | "repository": "ValerioLyndon/MAL-Public-List-Designs",
120 | "category": [
121 | "List Design"
122 | ]
123 | },
124 | {
125 | "repository": "ValerioLyndon/Theme-Customiser",
126 | "category": [
127 | "List Design"
128 | ]
129 | }
130 | ]
--------------------------------------------------------------------------------
/.github/workflows/accepted.yml:
--------------------------------------------------------------------------------
1 | name: Accepted Change
2 |
3 | on:
4 | issues:
5 | types: [closed]
6 |
7 | jobs:
8 | category:
9 | name: Accepted Category
10 | runs-on: ubuntu-latest
11 | if: contains(github.event.issue.labels.*.name, 'accepted') && contains(github.event.issue.labels.*.name, 'category request')
12 | steps:
13 | - name: Checkout Repository
14 | uses: actions/checkout@v6
15 | with:
16 | token: ${{ secrets.GITHUB_TOKEN }}
17 |
18 | - name: Parse Body
19 | uses: actions/github-script@v8
20 | env:
21 | BODY: ${{ github.event.issue.body }}
22 | with:
23 | github-token: ${{ secrets.GITHUB_TOKEN }}
24 | script: core.exportVariable("CATEGORY", process.env.BODY.split(/(?:\r?\n){2,}/gm)[1]);
25 |
26 | - name: Dispatch Workflow
27 | env:
28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
29 | CATEGORY: ${{ env.CATEGORY }}
30 | run: gh workflow run category.yml -f category=$CATEGORY
31 |
32 | item:
33 | name: Accepted Repository
34 | runs-on: ubuntu-latest
35 | if: contains(github.event.issue.labels.*.name, 'accepted') && contains(github.event.issue.labels.*.name, 'repository request')
36 | steps:
37 | - name: Checkout Repository
38 | uses: actions/checkout@v6
39 | with:
40 | token: ${{ secrets.GITHUB_TOKEN }}
41 |
42 | - name: Parse Body
43 | uses: actions/github-script@v8
44 | env:
45 | BODY: ${{ github.event.issue.body }}
46 | with:
47 | github-token: ${{ secrets.GITHUB_TOKEN }}
48 | script: |-
49 | core.exportVariable("REPOSITORY", process.env.BODY.split(/(?:\r?\n){2,}/gm)[1]);
50 | core.exportVariable("CATEGORY", process.env.BODY.split(/(?:\r?\n){2,}/gm)[3].replace(/ /gm, ""));
51 |
52 | - name: Dispatch Workflow
53 | env:
54 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
55 | REPOSITORY: ${{ env.REPOSITORY }}
56 | CATEGORY: ${{ env.CATEGORY }}
57 | run: gh workflow run repository.yml -f repository=$REPOSITORY -f category=$CATEGORY
58 |
59 | change:
60 | name: Accepted Change
61 | runs-on: ubuntu-latest
62 | if: contains(github.event.issue.labels.*.name, 'accepted') && contains(github.event.issue.labels.*.name, 'change request')
63 | steps:
64 | - name: Checkout Repository
65 | uses: actions/checkout@v6
66 | with:
67 | token: ${{ secrets.GITHUB_TOKEN }}
68 |
69 | - name: Parse Body
70 | uses: actions/github-script@v8
71 | env:
72 | BODY: ${{ github.event.issue.body }}
73 | with:
74 | github-token: ${{ secrets.GITHUB_TOKEN }}
75 | script: |-
76 | core.exportVariable("REPOSITORY", process.env.BODY.split(/(?:\r?\n){2,}/gm)[1]);
77 | core.exportVariable("CATEGORY", process.env.BODY.split(/(?:\r?\n){2,}/gm)[5].replace(/ /gm, ""));
78 |
79 | - name: Dispatch Workflow
80 | env:
81 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
82 | REPOSITORY: ${{ env.REPOSITORY }}
83 | CATEGORY: ${{ env.CATEGORY }}
84 | run: gh workflow run change.yml -f repository=$REPOSITORY -f category=$CATEGORY
--------------------------------------------------------------------------------
/.github/workflows/category.yml:
--------------------------------------------------------------------------------
1 | name: New Category
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | category:
7 | required: true
8 | description: Category
9 | type: string
10 |
11 | jobs:
12 | item:
13 | name: New Category
14 | runs-on: ubuntu-latest
15 | steps:
16 | - name: Checkout Repository
17 | uses: actions/checkout@v6
18 | with:
19 | token: ${{ secrets.GITHUB_TOKEN }}
20 |
21 | - name: Install Node
22 | uses: actions/setup-node@v6
23 | with:
24 | architecture: x64
25 | node-version: 20
26 |
27 | - name: Verify Branch Name
28 | uses: actions/github-script@v8
29 | env:
30 | BRANCH: ${{ github.event.inputs.category }}
31 | with:
32 | github-token: ${{ secrets.GITHUB_TOKEN }}
33 | script: |
34 | core.exportVariable("BRANCH", "category/" + process.env.BRANCH.replace(/[^\w]/gm, '-').toLowerCase());
35 |
36 | - name: Checkout New Branch
37 | env:
38 | BRANCH: ${{ env.BRANCH }}
39 | run: |-
40 | git checkout -B "$BRANCH"
41 |
42 | - name: Write Changes
43 | uses: actions/github-script@v8
44 | env:
45 | CATEGORY: ${{ github.event.inputs.category }}
46 | with:
47 | github-token: ${{ secrets.GITHUB_TOKEN }}
48 | script: |-
49 | const fs = require("fs");
50 | const path = require("path");
51 | const __dirname = path.resolve();
52 |
53 | const file = path.join(__dirname, "categories.json");
54 | let data = JSON.parse(fs.readFileSync(file, "utf-8"));
55 |
56 | const category = process.env.CATEGORY;
57 |
58 | data = data.filter(item => item !== category);
59 | data.push(category);
60 | data.sort();
61 |
62 | fs.writeFileSync(file, JSON.stringify(data, null, 4));
63 |
64 | const repository = path.join(__dirname, ".github", "ISSUE_TEMPLATE", "1-repository.yml");
65 | fs.writeFileSync(repository, (fs.readFileSync(repository, "utf-8").replace(/options: ?\[.*]/gm, `options: [${data.join(", ")}]`)));
66 |
67 | const change = path.join(__dirname, ".github", "ISSUE_TEMPLATE", "2-change.yml");
68 | fs.writeFileSync(change, (fs.readFileSync(change, "utf-8").replace(/options: ?\[.*]/gm, `options: [${data.join(", ")}]`)));
69 |
70 | - name: Commit Changes
71 | env:
72 | CATEGORY: ${{ github.event.inputs.category }}
73 | run: |-
74 | git config --global user.name "github-actions[bot]"
75 | git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
76 | git add -u
77 | git commit -m "Add new category '$CATEGORY'"
78 | git push origin HEAD
79 |
80 | - name: Create PR
81 | env:
82 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
83 | CATEGORY: ${{ github.event.inputs.category }}
84 | run: gh pr create -l "category request" -t "[New Category] $CATEGORY" -b "Automated category request for '$CATEGORY'" -a "Katsute"
85 |
86 | - name: Dispatch README
87 | env:
88 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
89 | BRANCH: ${{ env.BRANCH }}
90 | run: gh workflow run update.yml -r "$BRANCH"
--------------------------------------------------------------------------------
/.github/workflows/repository.yml:
--------------------------------------------------------------------------------
1 | name: New Repository
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | repository:
7 | required: true
8 | description: Repository name, 'OWNER/REPO'
9 | type: string
10 | category:
11 | required: true
12 | description: Categories, comma separated
13 | type: string
14 |
15 | jobs:
16 | item:
17 | name: New Repository
18 | runs-on: ubuntu-latest
19 | steps:
20 | - name: Checkout Repository
21 | uses: actions/checkout@v6
22 | with:
23 | token: ${{ secrets.GITHUB_TOKEN }}
24 |
25 | - name: Install Node
26 | uses: actions/setup-node@v6
27 | with:
28 | architecture: x64
29 | node-version: 20
30 |
31 | - name: Verify Branch Name
32 | uses: actions/github-script@v8
33 | env:
34 | BRANCH: ${{ github.event.inputs.repository }}
35 | with:
36 | github-token: ${{ secrets.GITHUB_TOKEN }}
37 | script: |-
38 | core.exportVariable("BRANCH", "repository/" + process.env.BRANCH.replace(/[^\w]/gm, '-').toLowerCase());
39 |
40 | - name: Checkout New Branch
41 | env:
42 | BRANCH: ${{ env.BRANCH }}
43 | run: |-
44 | git checkout -B "$BRANCH"
45 |
46 | - name: Write Changes
47 | uses: actions/github-script@v8
48 | env:
49 | REPOSITORY: ${{ github.event.inputs.repository }}
50 | CATEGORY: ${{ github.event.inputs.category }}
51 | with:
52 | github-token: ${{ secrets.GITHUB_TOKEN }}
53 | script: |-
54 | const fs = require("fs");
55 | const path = require("path");
56 | const __dirname = path.resolve();
57 |
58 | const file = path.join(__dirname, "repositories.json");
59 | let data = JSON.parse(fs.readFileSync(file, "utf-8"));
60 |
61 | const repository = process.env.REPOSITORY;
62 | const category = process.env.CATEGORY;
63 |
64 | data = data.filter(item => item.repository.toLowerCase() !== repository.toLowerCase());
65 |
66 | data.push({
67 | repository: repository,
68 | category: category.split(",").map(s => s.trim())
69 | });
70 |
71 | data.sort((a, b) => a.repository.toLowerCase() > b.repository.toLowerCase() ? 1 : -1);
72 |
73 | fs.writeFileSync(file, JSON.stringify(data, null, 4));
74 |
75 | - name: Commit Changes
76 | env:
77 | REPOSITORY: ${{ github.event.inputs.repository }}
78 | run: |-
79 | git config --global user.name "github-actions[bot]"
80 | git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
81 | git add -u
82 | git commit -m "Add new repository '$REPOSITORY'"
83 | git push origin HEAD
84 |
85 | - name: Create PR
86 | env:
87 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
88 | REPOSITORY: ${{ github.event.inputs.repository }}
89 | run: gh pr create -l "repository request" -t "[New Repository] $REPOSITORY" -b "Automated repository request for [$REPOSITORY](https://github.com/$REPOSITORY)" -a "Katsute"
90 |
91 | - name: Dispatch README
92 | env:
93 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
94 | BRANCH: ${{ env.BRANCH }}
95 | run: gh workflow run update.yml -r "$BRANCH"
--------------------------------------------------------------------------------
/.github/workflows/change.yml:
--------------------------------------------------------------------------------
1 | name: Change Request
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | repository:
7 | required: true
8 | description: Repository name, 'OWNER/REPO'
9 | type: string
10 | category:
11 | required: true
12 | description: Category, comma separated; Use 'DELETE' for deletion.
13 | type: string
14 |
15 | jobs:
16 | item:
17 | name: Change Request
18 | runs-on: ubuntu-latest
19 | steps:
20 | - name: Checkout Repository
21 | uses: actions/checkout@v6
22 | with:
23 | token: ${{ secrets.GITHUB_TOKEN }}
24 |
25 | - name: Install Node
26 | uses: actions/setup-node@v6
27 | with:
28 | architecture: x64
29 | node-version: 20
30 |
31 | - name: Verify Branch Name
32 | uses: actions/github-script@v8
33 | env:
34 | BRANCH: ${{ github.event.inputs.repository }}
35 | with:
36 | github-token: ${{ secrets.GITHUB_TOKEN }}
37 | script: |-
38 | core.exportVariable("BRANCH", "repository/" + process.env.BRANCH.replace(/[^\w]/gm, '-').toLowerCase());
39 |
40 | - name: Checkout New Branch
41 | env:
42 | BRANCH: ${{ env.BRANCH }}
43 | run: |-
44 | git checkout -B "$BRANCH"
45 |
46 | - name: Write Changes
47 | uses: actions/github-script@v8
48 | env:
49 | REPOSITORY: ${{ github.event.inputs.repository }}
50 | CATEGORY: ${{ github.event.inputs.category }}
51 | with:
52 | github-token: ${{ secrets.GITHUB_TOKEN }}
53 | script: |-
54 | const fs = require("fs");
55 | const path = require("path");
56 | const __dirname = path.resolve();
57 |
58 | const file = path.join(__dirname, "repositories.json");
59 | let data = JSON.parse(fs.readFileSync(file, "utf-8"));
60 |
61 | const repository = process.env.REPOSITORY;
62 | const category = process.env.CATEGORY;
63 |
64 | data = data.filter(item => item.repository.toLowerCase() !== repository.toLowerCase());
65 |
66 | if(category != "DELETE")
67 | data.push({
68 | repository: repository,
69 | category: category.split(",").map(s => s.trim())
70 | });
71 |
72 | data.sort((a, b) => a.repository.toLowerCase() > b.repository.toLowerCase() ? 1 : -1);
73 |
74 | fs.writeFileSync(file, JSON.stringify(data, null, 4));
75 |
76 | - name: Commit Changes
77 | env:
78 | REPOSITORY: ${{ github.event.inputs.repository }}
79 | run: |-
80 | git config --global user.name "github-actions[bot]"
81 | git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
82 | git add -u
83 | git commit -m "Modify '$REPOSITORY'"
84 | git push origin HEAD
85 |
86 | - name: Create PR
87 | env:
88 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
89 | REPOSITORY: ${{ github.event.inputs.repository }}
90 | run: gh pr create -l "change request" -t "[Change] $REPOSITORY" -b "Automated change request for [$REPOSITORY](https://github.com/$REPOSITORY)" -a "Katsute"
91 |
92 | - name: Dispatch README
93 | env:
94 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
95 | BRANCH: ${{ env.BRANCH }}
96 | run: gh workflow run update.yml -r "$BRANCH"
--------------------------------------------------------------------------------
/.github/workflows/update.yml:
--------------------------------------------------------------------------------
1 | name: README Update
2 |
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | - cron: 0 12 * 1-2,11-12 0
7 | - cron: 0 11 * 3-10 0
8 |
9 | jobs:
10 | item:
11 | name: Update README
12 | runs-on: ubuntu-latest
13 | steps:
14 | - name: Checkout Repository
15 | uses: actions/checkout@v6
16 | with:
17 | token: ${{ secrets.GITHUB_TOKEN }}
18 |
19 | - name: Install Node
20 | uses: actions/setup-node@v6
21 | with:
22 | architecture: x64
23 | node-version: 20
24 |
25 | - name: Write Changes
26 | uses: actions/github-script@v8
27 | with:
28 | github-token: ${{ secrets.GITHUB_TOKEN }}
29 | script: |-
30 | const fs = require("fs");
31 | const path = require("path");
32 | const __dirname = path.resolve();
33 |
34 | const README = path.join(__dirname, "README.md");
35 | const categories = JSON.parse(fs.readFileSync(path.join(__dirname, "categories.json"), "utf-8"));
36 | const repositories = JSON.parse(fs.readFileSync(path.join(__dirname, "repositories.json"), "utf-8"));
37 |
38 | let buf = "";
39 |
40 | for(const category of categories){
41 | buf += '\n';
42 | buf += ` * [${category}](#${category.toLowerCase().replace(/ /gm, '-')})`;
43 | }
44 |
45 | buf += '\n';
46 |
47 | fs.writeFileSync(README, fs.readFileSync(README, "utf-8").replace(/(?<=\n).*(?=\n?)/gms, buf + '\n'));
48 |
49 | buf = "";
50 |
51 | for(const category of categories){
52 | const repos = repositories.filter(r => r.category.includes(category)).sort((a, b) => a.repository.toLowerCase() > b.repository.toLowerCase() ? 1 : -1);
53 | if(repos.length > 0){
54 | buf += '\n';
55 | buf += `## ${category}`;
56 | buf += '\n';
57 | for(const r of repos){
58 | const repo = (await github.rest.repos.get({
59 | owner: r.repository.split('/')[0],
60 | repo: r.repository.split('/')[1]
61 | })).data;
62 |
63 | buf += '\n';
64 | buf += `
5 |
6 | | 15 | Submit a New Repository 16 | |