diff --git a/.github/ISSUE_TEMPLATE/new.md b/.github/ISSUE_TEMPLATE/new.md index 69f15142..ecda14f5 100644 --- a/.github/ISSUE_TEMPLATE/new.md +++ b/.github/ISSUE_TEMPLATE/new.md @@ -13,6 +13,8 @@ labels: new-challenge ## Info +Basic info of your challenge questions, + ```yaml difficulty: easy # medium / hard / extreme title: Your Question Name @@ -23,22 +25,25 @@ title: Your Question Name -Describe your question and give some examples. +Describe your question and give some examples. Markdown is supported here. ## Template +This is the template for challenger to start the coding, basically you just need to change the name of your generic/function and leave to implementation `any`. + ```ts type YourType = any ``` ## Test Cases -```ts -import { Equal, Expect } from '@type-challenges/utils' +Provide some test cases for your challenge, you can use some utils from `@type-challenges/utils` for assetion. + +```ts +import { Equal, Expect, ExpectFalse, NotEqual } from '@type-challenges/utils' -// your test cases type cases = [ Expect> ] diff --git a/.github/ISSUE_TEMPLATE/new.zh-CN.md b/.github/ISSUE_TEMPLATE/new.zh-CN.md new file mode 100644 index 00000000..8cfa02d1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/new.zh-CN.md @@ -0,0 +1,52 @@ +--- +name: 🇨🇳 新题目 +about: 新题目提案,PR 会根据 Issue 自动生成。 +title: "新题目" +labels: new-challenge, zh-CN +--- + +> 请按照以下的模版填充相应的内容,一个 PR 会自动生成并保持与本 Issue 的内容同步。 + +> 你不需要提供详细的答案或教学,但请保证题目可解。 + + +## 基本信息 + +```yaml +# 题目难度 +difficulty: easy # medium / hard / extreme + +# 题目标题 +title: 你的题目 + +# 题目标签 +#tags: union, array # separate by comma +``` + +## 题目 + + + +在这里描述你的题目并给出一些例子。支持使用 Markdown。 + + + +## 题目模版 + +以下是给予挑战者开始做题的代码模版,在大部分情况下你只需要修改类型名称使其符合你的题目与判题测试,实现的部分保持 `any` 即可。 + +```ts +type YourType = any +``` + +## 判题测试 + +请为你的题目提供一些判题测试,你可以使用 `@type-challenges/utils` 中提供的一些工具进行判断。 + +```ts +import { Equal, Expect, ExpectFalse, NotEqual } from '@type-challenges/utils' + +type cases = [ + Expect> +] +``` \ No newline at end of file diff --git a/actions/issue-pr.js b/actions/issue-pr.js index 2d8363b4..8f9a550a 100644 --- a/actions/issue-pr.js +++ b/actions/issue-pr.js @@ -5,6 +5,23 @@ const YAML = require('js-yaml') const slug = require('slug') const { PushCommit } = require('@type-challenges/octokit-create-pull-request') +const Messages = { + en: { + info: 'Info', + template: 'Template', + tests: 'Test Cases', + issue_reply: 'Pull Request created at #{0}', + issue_invalid_reply: 'Failed to parse the issue, please follow the template.', + }, + 'zh-CN': { + info: '基本信息', + template: '题目模版', + tests: '判题测试', + issue_reply: 'PR 已自动生成 #{0}', + issue_invalid_reply: 'Issue 格式不正确,请按照依照模版修正', + }, +} + /** * @param {ReturnType} github * @param {typeof import('@actions/github').context} context @@ -24,10 +41,12 @@ module.exports = async(github, context, core) => { // create pr for new challenge if (labels.includes('new-challenge')) { + const locale = labels.includes('zh-CN') ? 'zh-CN' : 'en' + const body = issue.body || '' - const infoRaw = getCodeBlock(body, 'Info', 'yaml') - const template = getCodeBlock(body, 'Template', 'ts') - const tests = getCodeBlock(body, 'Test Cases', 'ts') + const infoRaw = getCodeBlock(body, Messages[locale].info, 'yaml') + const template = getCodeBlock(body, Messages[locale].template, 'ts') + const tests = getCodeBlock(body, Messages[locale].tests, 'ts') const question = getCommentRange(body, 'question') /** @type {any} */ @@ -53,15 +72,25 @@ module.exports = async(github, context, core) => { }, null, 2), ) - if (!question || !template || !tests || !info) - return // TODO: warn user + // invalid issue + if (!question || !template || !tests || !info) { + await updateComment( + github, + context, + Messages[locale].issue_invalid_reply, + ) + return + } const { data: user } = await github.users.getByUsername({ username: issue.user.login }) - info.author = info.author || {} - info.author.github = issue.user.login - if (user) - info.author.name = user.name + // allow user to override the author info when filled in the Issue + if (!info.author) { + info.author = info.author || {} + info.author.github = issue.user.login + if (user) + info.author.name = user.name + } const { data: pulls } = await github.pulls.list({ owner: context.repo.owner, @@ -114,12 +143,11 @@ module.exports = async(github, context, core) => { core.info(JSON.stringify(pr, null, 2)) if (pr) { - await github.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: `Pull Request created at #${pr.number}!`, - }) + await updateComment( + github, + context, + Messages[locale].issue_reply.replace('{0}', pr.number.toString()), + ) } } } @@ -128,6 +156,41 @@ module.exports = async(github, context, core) => { } } +/** + * @param {ReturnType} github + * @param {typeof import('@actions/github').context} context + * @param {string} body + */ +async function updateComment(github, context, body) { + const { data: comments } = await github.issues.listComments({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + }) + + const existing_comment = comments.find(i => + i.user.login === 'github-actions[bot]', + ) + + if (existing_comment) { + return await github.issues.updateComment({ + comment_id: existing_comment.id, + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body, + }) + } + else { + return await github.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body, + }) + } +} + /** * @param {string} text * @param {string} title