mirror of
https://github.com/maciejpedzich/playlist-entry-validator.git
synced 2024-11-28 00:15:48 +01:00
Rework message format and handling valid playlists
This commit is contained in:
parent
27e2eec422
commit
724a52a28e
143
bot.ts
143
bot.ts
@ -1,4 +1,5 @@
|
|||||||
import { ApplicationFunction } from 'probot';
|
import { ApplicationFunction } from 'probot';
|
||||||
|
import getMetaData from 'metadata-scraper';
|
||||||
|
|
||||||
const bot: ApplicationFunction = (app) => {
|
const bot: ApplicationFunction = (app) => {
|
||||||
app.on(
|
app.on(
|
||||||
@ -8,7 +9,7 @@ const bot: ApplicationFunction = (app) => {
|
|||||||
const siQueryStart = '?si=';
|
const siQueryStart = '?si=';
|
||||||
|
|
||||||
const pull_number = context.payload.number;
|
const pull_number = context.payload.number;
|
||||||
const currentRepoData = {
|
const workingRepo = {
|
||||||
owner: context.payload.repository.owner.login,
|
owner: context.payload.repository.owner.login,
|
||||||
repo: context.payload.repository.name
|
repo: context.payload.repository.name
|
||||||
};
|
};
|
||||||
@ -21,34 +22,42 @@ const bot: ApplicationFunction = (app) => {
|
|||||||
const removePathFromFilename = (filename: string) =>
|
const removePathFromFilename = (filename: string) =>
|
||||||
filename.replace(registryDirectoryPath, '');
|
filename.replace(registryDirectoryPath, '');
|
||||||
|
|
||||||
const upsertReview = async (body: string, review_id?: number) => {
|
const upsertReview = async (
|
||||||
|
review_id: number | undefined,
|
||||||
|
body: string,
|
||||||
|
event: 'REQUEST_CHANGES' | 'COMMENT'
|
||||||
|
) => {
|
||||||
if (review_id) {
|
if (review_id) {
|
||||||
await context.octokit.pulls.updateReview({
|
const { data } = await context.octokit.pulls.updateReview({
|
||||||
...currentRepoData,
|
...workingRepo,
|
||||||
pull_number,
|
pull_number,
|
||||||
review_id,
|
review_id,
|
||||||
body
|
body
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return data.id;
|
||||||
} else {
|
} else {
|
||||||
await context.octokit.pulls.createReview({
|
const { data } = await context.octokit.pulls.createReview({
|
||||||
...currentRepoData,
|
...workingRepo,
|
||||||
pull_number,
|
pull_number,
|
||||||
event: 'REQUEST_CHANGES',
|
event,
|
||||||
body: `Hey there, thank you for taking interest in this project!\n${body}`
|
body
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return data.id;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const isAllowlistedRepo = repoAllowlist.find(
|
const allowlistedRepo = repoAllowlist.find(
|
||||||
({ owner, repo }) =>
|
({ owner, repo }) =>
|
||||||
currentRepoData.owner === owner && currentRepoData.repo === repo
|
workingRepo.owner === owner && workingRepo.repo === repo
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!isAllowlistedRepo) return;
|
if (!allowlistedRepo) return;
|
||||||
|
|
||||||
const { data: prFiles } = await context.octokit.pulls.listFiles({
|
const { data: prFiles } = await context.octokit.pulls.listFiles({
|
||||||
...currentRepoData,
|
...workingRepo,
|
||||||
pull_number
|
pull_number
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -57,78 +66,124 @@ const bot: ApplicationFunction = (app) => {
|
|||||||
status === 'added' && filename.startsWith(registryDirectoryPath)
|
status === 'added' && filename.startsWith(registryDirectoryPath)
|
||||||
);
|
);
|
||||||
|
|
||||||
const filesWithSiQuery = filesToVerify.filter(({ filename }) =>
|
|
||||||
filename.includes(siQueryStart)
|
|
||||||
);
|
|
||||||
|
|
||||||
const playlistLookupResults = await Promise.all(
|
const playlistLookupResults = await Promise.all(
|
||||||
filesToVerify.map(async ({ filename }) => {
|
filesToVerify.map(async ({ filename }) => {
|
||||||
const filenameWithoutPath = removePathFromFilename(filename);
|
const filenameWithoutPath = removePathFromFilename(filename);
|
||||||
const spotifyResponse = await fetch(
|
const url = `https://open.spotify.com/playlist/${filenameWithoutPath}`;
|
||||||
`https://open.spotify.com/playlist/${filenameWithoutPath}`
|
|
||||||
);
|
const spotifyResponse = await fetch(url);
|
||||||
|
const found = spotifyResponse.status === 200;
|
||||||
|
let info: string | null = null;
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
const html = await spotifyResponse.text();
|
||||||
|
const { title, description } = await getMetaData({ html });
|
||||||
|
const playlistMeta = (description || '')
|
||||||
|
.split(' · ')
|
||||||
|
.filter((text) => text !== 'Playlist');
|
||||||
|
|
||||||
|
info = [title, ...playlistMeta].join(' · ');
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
filename: removePathFromFilename(filename),
|
filename: removePathFromFilename(filename),
|
||||||
found: spotifyResponse.status === 200
|
found,
|
||||||
|
info,
|
||||||
|
url
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const validEntries = playlistLookupResults.filter(
|
||||||
|
({ found, filename }) => found && !filename.includes(siQueryStart)
|
||||||
|
);
|
||||||
|
|
||||||
|
const entriesWithSiQuery = playlistLookupResults.filter(
|
||||||
|
({ found, filename }) => found && filename.includes(siQueryStart)
|
||||||
|
);
|
||||||
|
|
||||||
const notFoundPlaylists = playlistLookupResults.filter(
|
const notFoundPlaylists = playlistLookupResults.filter(
|
||||||
({ found }) => !found
|
({ found }) => !found
|
||||||
);
|
);
|
||||||
|
|
||||||
const { data: priorReviews } = await context.octokit.pulls.listReviews({
|
const { data: priorReviews } = await context.octokit.pulls.listReviews({
|
||||||
...currentRepoData,
|
...workingRepo,
|
||||||
pull_number
|
pull_number
|
||||||
});
|
});
|
||||||
|
|
||||||
const [existingReview] = priorReviews;
|
const [existingReview] = priorReviews;
|
||||||
|
const canMergeMessage = `🎉 @${workingRepo.owner} can merge your pull request! 🎉`;
|
||||||
|
|
||||||
|
let identifiedPlaylistsText = '';
|
||||||
|
let renameRequiredText = '';
|
||||||
|
let notFoundText = '';
|
||||||
|
let successText = canMergeMessage;
|
||||||
|
let reviewEvent: 'REQUEST_CHANGES' | 'COMMENT' = 'COMMENT';
|
||||||
|
|
||||||
|
if (validEntries.length > 0) {
|
||||||
|
const playlistLinks = validEntries
|
||||||
|
.map(({ url, info }) => `- [${info}](${url})`)
|
||||||
|
.join('\n');
|
||||||
|
|
||||||
|
identifiedPlaylistsText = `### ✅ These playlists were indentified:\n${playlistLinks}`;
|
||||||
|
}
|
||||||
|
|
||||||
if (notFoundPlaylists.length > 0) {
|
if (notFoundPlaylists.length > 0) {
|
||||||
const renameList = notFoundPlaylists
|
const renameList = notFoundPlaylists
|
||||||
.map(({ filename }) => `- ${filename}`)
|
.map(({ filename }) => `- ${filename}`)
|
||||||
.join('\n');
|
.join('\n');
|
||||||
|
|
||||||
const body = `It looks like the following playlists don't exist:\n${renameList}`;
|
successText = '';
|
||||||
|
reviewEvent = 'REQUEST_CHANGES';
|
||||||
|
notFoundText = `### ❌ Playlists for these entries were not found:\n${renameList}`;
|
||||||
|
}
|
||||||
|
|
||||||
await upsertReview(body, existingReview?.id);
|
if (entriesWithSiQuery.length > 0) {
|
||||||
} else if (filesWithSiQuery.length > 0) {
|
const renameList = entriesWithSiQuery
|
||||||
const renameList = filesWithSiQuery
|
|
||||||
.map(({ filename }) => {
|
.map(({ filename }) => {
|
||||||
const filenameWithoutPath = removePathFromFilename(filename);
|
const filenameWithoutPath = removePathFromFilename(filename);
|
||||||
const [targetFilename] = filenameWithoutPath.split(siQueryStart);
|
const [targetFilename] = filenameWithoutPath.split(siQueryStart);
|
||||||
|
|
||||||
return `- Rename ${filenameWithoutPath} to **${targetFilename}**`;
|
return `- From ${filenameWithoutPath} to **${targetFilename}**`;
|
||||||
})
|
})
|
||||||
.join('\n');
|
.join('\n');
|
||||||
|
|
||||||
const body = `All new files point to existing playlists, but you have to:\n${renameList}`;
|
successText = '';
|
||||||
|
reviewEvent = 'REQUEST_CHANGES';
|
||||||
|
renameRequiredText = `### ⚠️ These entries have to be renamed:\n${renameList}`;
|
||||||
|
}
|
||||||
|
|
||||||
await upsertReview(body, existingReview?.id);
|
const reviewBody = [
|
||||||
} else {
|
identifiedPlaylistsText,
|
||||||
if (existingReview) {
|
renameRequiredText,
|
||||||
await context.octokit.pulls.dismissReview({
|
notFoundText,
|
||||||
...currentRepoData,
|
successText
|
||||||
pull_number,
|
]
|
||||||
review_id: existingReview.id,
|
.filter(Boolean)
|
||||||
message: '🎉 Your pull request can be merged! 🎉'
|
.join('\n\n');
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Change successful validation handling
|
await upsertReview(existingReview?.id, reviewBody, reviewEvent);
|
||||||
// await context.octokit.pulls.merge({
|
|
||||||
// ...currentRepoData,
|
if (
|
||||||
// pull_number
|
renameRequiredText === '' &&
|
||||||
// });
|
notFoundText === '' &&
|
||||||
|
existingReview?.id
|
||||||
|
) {
|
||||||
|
await context.octokit.pulls.dismissReview({
|
||||||
|
...workingRepo,
|
||||||
|
pull_number,
|
||||||
|
review_id: existingReview.id,
|
||||||
|
message: 'All new entries are now valid!'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
|
||||||
await context.octokit.pulls.createReview({
|
await context.octokit.pulls.createReview({
|
||||||
...currentRepoData,
|
...workingRepo,
|
||||||
pull_number,
|
pull_number,
|
||||||
event: 'COMMENT',
|
event: 'COMMENT',
|
||||||
body: 'Something went wrong while verifying your entries! @mackorone should handle it shortly.'
|
body: `Something went wrong while verifying new entries! @${workingRepo.owner} should handle it shortly...`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user