Compare commits
14 Commits
a6a6f51d00
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
259d292b97
|
|||
|
d7752c9319
|
|||
|
547a43258b
|
|||
|
db4481dd55
|
|||
|
db053567c2
|
|||
|
f415179c8d
|
|||
|
e61174a62e
|
|||
|
f2c99ea418
|
|||
|
87b7723e32
|
|||
|
66531d5b54
|
|||
|
4ecd9df628
|
|||
| 3c55c3243e | |||
|
b56a25e762
|
|||
|
daff508183
|
@@ -1,14 +1,14 @@
|
|||||||
FROM node:lts-alpine AS build
|
FROM node:lts-alpine AS build
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
RUN npm ci
|
RUN npm i
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
FROM node:lts-alpine AS runtime
|
FROM node:lts-alpine AS runtime
|
||||||
|
USER node
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
ENV NODE_ENV production
|
ENV NODE_ENV production
|
||||||
USER node
|
|
||||||
COPY --chown=node:node package*.json ./
|
COPY --chown=node:node package*.json ./
|
||||||
RUN npm ci --omit=dev
|
RUN npm ci --omit=dev
|
||||||
COPY --from=build --chown=node:node /app/dist ./dist
|
COPY --from=build --chown=node:node /app/dist ./dist
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
GitHub bot that automatically verifies pull requests with new playlist entries for [spotify-playlist-archive](https://github.com/mackorone/spotify-playlist-archive) repo.
|
GitHub bot that automatically verifies pull requests with new playlist entries for [spotify-playlist-archive](https://github.com/mackorone/spotify-playlist-archive) repo.
|
||||||
|
|
||||||
|
[Example of a validated pull request](https://github.com/mackorone/spotify-playlist-archive/pull/408)
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|||||||
70
appFn.ts
70
appFn.ts
@@ -7,9 +7,7 @@ import { getPlaylistIdFromUrl } from './getPlaylistIdFromUrl';
|
|||||||
|
|
||||||
type ReviewEvent = 'REQUEST_CHANGES' | 'COMMENT' | 'APPROVE';
|
type ReviewEvent = 'REQUEST_CHANGES' | 'COMMENT' | 'APPROVE';
|
||||||
|
|
||||||
const appFn: ApplicationFunction = (app: Probot, { getRouter }) => {
|
const appFn: ApplicationFunction = (app: Probot) => {
|
||||||
getRouter!('/ping').get('/pong', (_, res) => res.sendStatus(200));
|
|
||||||
|
|
||||||
app.on(
|
app.on(
|
||||||
['pull_request.opened', 'pull_request.synchronize'],
|
['pull_request.opened', 'pull_request.synchronize'],
|
||||||
async ({ payload, octokit, log }) => {
|
async ({ payload, octokit, log }) => {
|
||||||
@@ -31,14 +29,14 @@ const appFn: ApplicationFunction = (app: Probot, { getRouter }) => {
|
|||||||
body: string
|
body: string
|
||||||
) => {
|
) => {
|
||||||
if (review_id) {
|
if (review_id) {
|
||||||
await octokit.pulls.updateReview({
|
await octokit.rest.pulls.updateReview({
|
||||||
...workingRepo,
|
...workingRepo,
|
||||||
pull_number,
|
pull_number,
|
||||||
review_id,
|
review_id,
|
||||||
body
|
body
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await octokit.pulls.createReview({
|
await octokit.rest.pulls.createReview({
|
||||||
...workingRepo,
|
...workingRepo,
|
||||||
pull_number,
|
pull_number,
|
||||||
event,
|
event,
|
||||||
@@ -49,6 +47,7 @@ const appFn: ApplicationFunction = (app: Probot, { getRouter }) => {
|
|||||||
|
|
||||||
const repoAllowlist = [
|
const repoAllowlist = [
|
||||||
{ owner: 'mackorone', repo: 'spotify-playlist-archive' },
|
{ owner: 'mackorone', repo: 'spotify-playlist-archive' },
|
||||||
|
{ owner: 'mackorone', repo: 'spotify-playlist-archive-2' },
|
||||||
{ owner: 'maciejpedzich', repo: 'bot-testing-ground' }
|
{ owner: 'maciejpedzich', repo: 'bot-testing-ground' }
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -61,7 +60,7 @@ const appFn: ApplicationFunction = (app: Probot, { getRouter }) => {
|
|||||||
if (!isAllowlistedRepo) return;
|
if (!isAllowlistedRepo) return;
|
||||||
|
|
||||||
type PRFileArray = Awaited<
|
type PRFileArray = Awaited<
|
||||||
ReturnType<typeof octokit.pulls.listFiles>
|
ReturnType<typeof octokit.rest.pulls.listFiles>
|
||||||
>['data'];
|
>['data'];
|
||||||
|
|
||||||
const prFiles: PRFileArray = [];
|
const prFiles: PRFileArray = [];
|
||||||
@@ -72,7 +71,7 @@ const appFn: ApplicationFunction = (app: Probot, { getRouter }) => {
|
|||||||
while (isLoadingPages) {
|
while (isLoadingPages) {
|
||||||
await setTimeout(timeToRateLimitReset);
|
await setTimeout(timeToRateLimitReset);
|
||||||
|
|
||||||
const { data, headers } = await octokit.pulls.listFiles({
|
const { data, headers } = await octokit.rest.pulls.listFiles({
|
||||||
...workingRepo,
|
...workingRepo,
|
||||||
pull_number,
|
pull_number,
|
||||||
page
|
page
|
||||||
@@ -132,7 +131,11 @@ const appFn: ApplicationFunction = (app: Probot, { getRouter }) => {
|
|||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
const html = await spotifyResponse.text();
|
const html = await spotifyResponse.text();
|
||||||
const { author: authorUrl, description } = await getMetaData({
|
const {
|
||||||
|
// author: authorUrl,
|
||||||
|
description,
|
||||||
|
title
|
||||||
|
} = await getMetaData({
|
||||||
html,
|
html,
|
||||||
customRules: {
|
customRules: {
|
||||||
author: {
|
author: {
|
||||||
@@ -146,32 +149,39 @@ const appFn: ApplicationFunction = (app: Probot, { getRouter }) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let authorName = (authorUrl as string).endsWith('/user/spotify')
|
// let authorName = (authorUrl as string).endsWith('/user/spotify')
|
||||||
? 'Spotify'
|
// ? 'Spotify'
|
||||||
: '';
|
// : '';
|
||||||
|
|
||||||
if (authorName === '') {
|
// if (authorName === '') {
|
||||||
const playlistAuthorResponse = await fetch(authorUrl as string);
|
// const playlistAuthorResponse = await fetch(authorUrl as string);
|
||||||
|
|
||||||
if (!playlistAuthorResponse.ok)
|
// if (!playlistAuthorResponse.ok)
|
||||||
throw new Error(
|
// throw new Error(
|
||||||
`Received ${playlistAuthorResponse.status} status code from ${authorUrl}`
|
// `Received ${playlistAuthorResponse.status} status code from ${authorUrl}`
|
||||||
);
|
// );
|
||||||
|
|
||||||
const authorPageHtml = await playlistAuthorResponse.text();
|
// const authorPageHtml = await playlistAuthorResponse.text();
|
||||||
const { title: authorPageTitle } = await getMetaData({
|
// const { title: authorPageTitle } = await getMetaData({
|
||||||
html: authorPageHtml
|
// html: authorPageHtml
|
||||||
});
|
// });
|
||||||
|
|
||||||
authorName = authorPageTitle as string;
|
// authorName = authorPageTitle as string;
|
||||||
}
|
// }
|
||||||
|
|
||||||
const playlistMeta = (description || '')
|
// const playlistMeta = (description || '')
|
||||||
.split(' · ')
|
// .split(' · ')
|
||||||
.filter((text) => text !== 'Playlist')
|
// .filter((text) => text !== 'Playlist')
|
||||||
.concat(authorName as string);
|
// .concat(authorName as string);
|
||||||
|
|
||||||
details = playlistMeta.join(' · ');
|
// details = playlistMeta.join(' · ');
|
||||||
|
details = (
|
||||||
|
title +
|
||||||
|
' · ' +
|
||||||
|
description!.replace('Playlist · ', '')
|
||||||
|
)
|
||||||
|
.replace(/\s+/g, ' ')
|
||||||
|
.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
numProcessedEntries++;
|
numProcessedEntries++;
|
||||||
@@ -236,7 +246,7 @@ const appFn: ApplicationFunction = (app: Probot, { getRouter }) => {
|
|||||||
if (urlFilenameEntries.length > 0) {
|
if (urlFilenameEntries.length > 0) {
|
||||||
successText = '';
|
successText = '';
|
||||||
|
|
||||||
const forkPageUrl = payload.pull_request.head.repo.html_url;
|
const forkPageUrl = payload.pull_request.head.repo?.html_url;
|
||||||
const httpsDirUrl = `${forkPageUrl}/tree/main/playlists/registry/https:`;
|
const httpsDirUrl = `${forkPageUrl}/tree/main/playlists/registry/https:`;
|
||||||
|
|
||||||
const baseCreateUrl = `${forkPageUrl}/new/main/playlists/registry/FOO`;
|
const baseCreateUrl = `${forkPageUrl}/new/main/playlists/registry/FOO`;
|
||||||
@@ -276,7 +286,7 @@ const appFn: ApplicationFunction = (app: Probot, { getRouter }) => {
|
|||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join('\n\n');
|
.join('\n\n');
|
||||||
|
|
||||||
const { data: reviews } = await octokit.pulls.listReviews({
|
const { data: reviews } = await octokit.rest.pulls.listReviews({
|
||||||
...workingRepo,
|
...workingRepo,
|
||||||
pull_number
|
pull_number
|
||||||
});
|
});
|
||||||
|
|||||||
6
index.ts
6
index.ts
@@ -1,4 +1,8 @@
|
|||||||
import { run } from 'probot';
|
import { run } from 'probot';
|
||||||
import appFn from './appFn';
|
import appFn from './appFn';
|
||||||
|
|
||||||
run(appFn);
|
run(appFn).then((server) => {
|
||||||
|
process.on('SIGTERM', async () => {
|
||||||
|
await server.stop();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
6201
package-lock.json
generated
6201
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -17,16 +17,16 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/maciejpedzich/mackorone-playlist-pr-bot#readme",
|
"homepage": "https://github.com/maciejpedzich/mackorone-playlist-pr-bot#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"metadata-scraper": "^0.2.60",
|
"metadata-scraper": "^0.2.61",
|
||||||
"probot": "^12.3.3",
|
"probot": "^14.2.4",
|
||||||
"promise-throttle-all": "^1.1.1"
|
"promise-throttle-all": "^1.1.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.14.11",
|
"@types/node": "^22.15.29",
|
||||||
"ts-node-dev": "^2.0.0",
|
"ts-node-dev": "^2.0.0",
|
||||||
"typescript": "^4.8.3"
|
"typescript": "^5.9.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user