您知道,这不是悬疑的动作故事,而是作为软件自由式工程师的有趣动作的故事。
作为SFE,我很幸运能够认识这么多窥视自己,他们不仅奉献自己的钱,还感觉到我吗? 听起来太挑衅了?
金钱很重要,但一切都不是一切,你们! - 我
无论如何,回到手头的话题,Homie!此动作是隐喻故事-SCP '的关键组成部分,因为此动作,所有故事都分发给了公众。
动作的想法
令人惊讶的是,@mkubdev简单而绝妙的主意使我作为自由式的热情将这些话语制作成一个以隐喻风格包裹的惊人故事。
动作结构
模板故事
故事模板是将根据封闭问题分发的故事的占位符。
---
layout: post
title: {title}
author: {author}
created_at: {created_at}
language: {language}
---
{content}
slugify和git文件
Slugify
这是我朋友的一些JavaScript模块,称为“ Slugify.js”!目标是将一些文本字符串作为输入,然后将其变成“ slug”格式,YA DIG? “ slug”是字符串的URL友好版本,其中所有字符都在小写字母中,空格被连字符替换(“ - ”),并且所有非字符的字符都被删除。而且我只需要一行写一行,毫不奇怪,伙计!
// Filename: slugify.js
module.exports = text => text.toString().normalize('NFKD').toLowerCase().trim().replace(/\s+/g, '-').replace(/[^\w\-]+/g, '').replace(/\-\-+/g, '-').replace(/\-$/g, '');
检查一下,朋克!这是一条时髦的新鲜线的低点!
This code exports a function as a module so it can be imported into other files. It takes an input text and casts it to a string type (just in case it isn't already a string). It normalizes the string using the Unicode normalization form "NFKD", which replaces accented characters with their base equivalents. It converts the string to lowercase. It removes leading or trailing white space from the string (optional). It replaces one or more consecutive white space characters with a single hyphen ("-"). It removes all non-word characters (including spaces) from the string. It replaces any consecutive occurrence of two or more hyphens with a single hyphen. It removes any remaining hyphens from the string.
因此,当您在文本字符串上使用此函数时,它将返回已转换为slug格式的新字符串,从而易于用作URL或标识符。
git
// Filename: git.js
module.exports = {
ghBotUsername: 'github-actions[bot]',
ghBotEmail: '41898282+github-actions[bot]@users.noreply.github.com',
}
yo yo!查看此代码,Dawg!这就是这个机器人,对吗?机器人有一个名字,伙计!它叫做ghBotUsername
!这不仅是任何名字,兄弟!这是github-actions[bot]
的名字!就像,超级酷,对吧?
等等,等等!机器人甚至有一封电子邮件,伙计!是ghBotEmail
!就像,真的很疯狂!它具有所有这些数字,符号和内容!就像41898282+github-actions[bot]@users.noreply.github.com
!你甚至可以处理吗?似乎这个机器人是完全合法的,带有自己的特殊电子邮件和所有内容!
动作yay-mlðð££
name: "Check Closed Issues and Generate New Story"
description: "Punk will check cloesed Issue and generate story"
inputs:
github-token:
description: "GitHub token for repo"
required: true
issue-message:
description: "Message to reply to new issue as a comment"
default: "Thank you for creating an Issue and contributing to our community project :tada:. Someone from the community will get back to you soon, usually within 24 hours"
pr-message:
description: "Message to reply to new pull request as a comment"
default: "Thank you for creating a Pull Request and contributing to our community project :tada:. Someone from the community will get back to you soon, usually within 24 hours"
footer:
description: "Append issue and pull request message with this message"
default: ""
runs:
using: "node16"
main: "index.js"
等一下,为什么那里有这么多的输入参数? Ohmypunk !!!
好吧,我会非常简短地解释。因此,这是解释。
Yoooooo,您可以摇晃以了解为什么上面的github操作文件中有一些输入参数。
(请注意:“ shake”在这里表示“快速上下滚动,以随意而有趣的方式查看上下文。)ð
主要动作
我故意没有依次编写这些步骤,因为它们已经非常普遍且普通。将此帖子视为真正抽象的,抽象的绘画。
// Filename: index.js
const core = require('@actions/core');
const github = require('@actions/github');
const greetingContributor = require('./scripts/greetingContributor');
const storyGenerator = require('./scripts/storyGenerator');
(async () => {
try {
const githubToken = core.getInput('github-token', { required: true });
const issueMessage = core.getInput('issue-message');
const prMessage = core.getInput('pr-message');
const footer = core.getInput('footer');
const client = github.getOctokit(githubToken);
const context = github.context;
switch (context.payload.action) {
case 'closed':
await storyGenerator(client, context)
break;
case 'opened':
await greetingContributor(client, context, issueMessage, prMessage, footer)
break;
default:
console.log('No action, skipping');
core.notice('No action, skipping!');
break;
}
} catch (error) {
core.setFailed(error.message);
}
})()
注入核心包(无论您叫什么)
您肯定在上面看到了这些代码,不是吗?
const core = require('@actions/core');
const github = require('@actions/github');
是的!注入这两个软件包, ðcomposer
npm
npm install @actions/core @action/github
您还看到了这条代码:
const greetingContributor = require('./scripts/greetingContributor');
const storyGenerator = require('./scripts/storyGenerator');
那么,它们来自哪里,它们看起来像什么?
问候贡献者
迎接StreetCommunityProgrammer/metaphore
GitHub存储库中贡献者的动作。
const core = require('@actions/core');
module.exports = async (client, context, issueMessage, prMessage, footer) => {
try {
const issue = await client.rest.issues.get({
owner: context.issue.owner,
repo: context.issue.repo,
issue_number: context.issue.number,
})
const issueData = issue.data
const labels = issueData.labels.map(label => label.name)
if (context.payload.action !== 'opened' || labels.includes('story::comment') === true) {
console.log('No issue / pull request was opened, skipping');
return;
}
const footerTags = `<p>${footer}</p>`;
if (!!context.payload.issue) {
await client.rest.issues.createComment({
owner: context.issue.owner,
repo: context.issue.repo,
issue_number: context.issue.number,
body: issueMessage + footerTags
});
} else {
await client.rest.pulls.createReview({
owner: context.issue.owner,
repo: context.issue.repo,
pull_number: context.issue.number,
body: prMessage + footerTags,
event: 'COMMENT'
});
}
} catch (error) {
core.setFailed(error.message);
}
}
当动作触发贡献者时(当context.payload.action
=== opened
)时,结果就是这样。
故事动作
hmmmmmmmmm ....这是隐喻故事的最重要功能和功能 - scp 网站。因为网站上显示的所有故事都是从这里创建的。
module.exports = async (client, context) => {
try {
const issue = await client.rest.issues.get({
owner: context.issue.owner,
repo: context.issue.repo,
issue_number: context.issue.number,
})
const assignees = issue.data.assignees
const isReviewerPresence = assignees.some(assignee => ['darkterminal', 'mkubdev'].includes(assignee.login))
if (issue.data.state === 'closed' && isReviewerPresence) {
const labels = issue.data.labels.map(label => label.name)
const metaphors = [
['css', 'css'],
['golang', 'golang'],
['javascript', 'javascript'],
['java', 'java'],
['maths', 'maths'],
['python', 'python'],
['php', 'php'],
['physics', 'physics'],
['ruby', 'ruby'],
['rust', 'rust'],
['zig', 'zig']
]
const isMetaphor = metaphors.some(([category, label]) => labels.every(l => ['metaphore', category].includes(l)))
if (isMetaphor) {
const [category, label] = metaphors.find(([category, label]) => labels.every(l => ['metaphore', category].includes(l)))
console.log(`Is ${category} metaphor`)
createMetaphorFile(client, issue.data, context, label)
}
addLabelToClosedIssue(client, context.issue.owner, context.issue.repo, context.issue.number, [...labels, 'published'])
}
} catch (error) {
console.log(`Error on storyGenerator: ${error}`)
return false
}
}
这是我写这篇文章之前的代码,它看起来真的很尴尬,并且肯定违反了“干净代码”的原则。
module.exports = async (client, context) => {
try {
const issue = await client.rest.issues.get({
owner: context.issue.owner,
repo: context.issue.repo,
issue_number: context.issue.number,
})
const issueData = issue.data
const assignees = issue.data.assignees
const isReviewerPresence = assignees.some(assignee => {
return assignee.login === "darkterminal" || assignee.login === "mkubdev";
});
if (issueData.state === 'closed' && isReviewerPresence) {
const labels = issueData.labels.map(label => label.name)
// Metaphor Categories
const isCssMetaphor = labels.every(label => ['metaphore', 'css'].includes(label))
const isGolangMetaphor = labels.every(label => ['metaphore', 'golang'].includes(label))
const isJavaScriptMetaphor = labels.every(label => ['metaphore', 'javascript'].includes(label))
const isJavaMetaphor = labels.every(label => ['metaphore', 'java'].includes(label))
const isMathsMetaphor = labels.every(label => ['metaphore', 'maths'].includes(label))
const isPythonMetaphor = labels.every(label => ['metaphore', 'python'].includes(label))
const isPhpMetaphor = labels.every(label => ['metaphore', 'php'].includes(label))
const isPhysicsMetaphor = labels.every(label => ['metaphore', 'physics'].includes(label))
const isRubyMetaphor = labels.every(label => ['metaphore', 'ruby'].includes(label))
const isRustMetaphor = labels.every(label => ['metaphore', 'rust'].includes(label))
const isZigMetaphor = labels.every(label => ['metaphore', 'zig'].includes(label))
if (isCssMetaphor) {
console.log(`Is css metaphor`)
createMetaphorFile(client, issueData, context, 'css')
} else if (isGolangMetaphor) {
console.log(`Is golang metaphor`)
createMetaphorFile(client, issueData, context, 'golang')
} else if (isJavaScriptMetaphor) {
console.log(`Is javascript metaphor`)
createMetaphorFile(client, issueData, context, 'javascript')
} else if (isJavaMetaphor) {
console.log(`Is java metaphor`)
createMetaphorFile(client, issueData, context, 'java')
} else if (isMathsMetaphor) {
console.log(`Is maths metaphor`)
createMetaphorFile(client, issueData, context, 'maths')
} else if (isPythonMetaphor) {
console.log(`Is python metaphor`)
createMetaphorFile(client, issueData, context, 'python')
} else if (isPhpMetaphor) {
console.log(`Is php metaphor`)
createMetaphorFile(client, issueData, context, 'php')
} else if (isPhysicsMetaphor) {
console.log(`Is physics metaphor`)
createMetaphorFile(client, issueData, context, 'physics')
} else if (isRubyMetaphor) {
console.log(`Is ruby metaphor`)
createMetaphorFile(client, issueData, context, 'ruby')
} else if (isRustMetaphor) {
console.log(`Is rust metaphor`)
createMetaphorFile(client, issueData, context, 'rust')
} else if (isZigMetaphor) {
console.log(`Is zig metaphor`)
createMetaphorFile(client, issueData, context, 'zig')
}
addLabelToClosedIssue(client, context.issue.owner, context.issue.repo, context.issue.number, [...labels, 'published'])
}
} catch (error) {
console.log(`Erorr on storyGenerator: ${error}`)
return false
}
}
男人,此代码中的if-else
语句太多了。我们将这个Barbarian Coding
称为我来自的地方,哈哈! ð
尚未提及的另一个功能
createMetaphorFile
,addLabelToClosedIssue
和createFileContent
。 3个非常漂亮的功能。
1. createMetaphorFile
功能
/**
* Creates a new metaphor file in the specified category, based on the provided issue data and context.
* @async
* @function createMetaphorFile
* @param {Object} client - The client object containing information about the GitHub repository and issue, including owner, repo, and issue number.
* @param {Object} issueData - The issue data object containing information about the issue, including title, user, created date, and body content.
* @param {Object} context - The context object containing information about the GitHub repository and issue, including owner, repo, and issue number.
* @param {string} category - The category of the metaphor file to create.
* @returns {Promise} A Promise that resolves when the metaphor file has been created in the GitHub repository.
*/
async function createMetaphorFile(client, issueData, context, category) {
const metaphorTitle = slugify(issueData.title);
const template = `---
layout: post
title: {title}
author: {author}
created_at: {created_at}
language: {language}
---
{content}`;
const placeholders = ['{title}', '{author}', '{created_at}', '{language}', '{content}'];
const values = [
issueData.title,
issueData.user.login,
issueData.created_at,
category,
issueData.body,
];
const replacedTemplate = placeholders.reduce((template, placeholder, index) => {
return template.replace(new RegExp(placeholder, 'g'), values[index]);
}, template);
console.log('Replacement result: ' + JSON.stringify(replacedTemplate, undefined, 2))
const metaphorContent = Buffer.from(replacedTemplate).toString('base64');
const createContent = await createFileContent({
client: client,
owner: context.issue.owner,
repo: context.issue.repo,
path: `public/collections/stories/${category}/${metaphorTitle}.md`,
message: `docs(generate): new metaphor from @${issueData.user.login}`,
content: metaphorContent,
});
console.log(`Content Metadata: ${JSON.stringify(createContent, undefined, 2)}`);
}
让我告诉您一个关于神奇功能“ createmetaphorfile”的时髦故事。此功能就像一个超级英雄,有能力使用GitHub问题中的数据创建全新的隐喻文件。它使用称为javascript的时髦语言完成了所有这些。
这个超级英雄功能具有一些特殊的帮助者,以使其工作更轻松。他们被命名为客户,发行和上下文,就像造物主义者的搭档一样。他们帮助它读写到GitHub存储库,并获取有关隐喻将基于的问题的重要信息。
,但是CreateMetaphorFile的最重要部分是其秘密代码称为“类别”。这就像一个神奇的咒语,可以将原始问题数据转化为一个令人讨厌的新故事。
CreateMetaphorFile所做的第一件事是使用一个称为“ slugify”的咒语将问题的标题转化为sl。这就像将常规句子变成一个时髦的小写字符串,没有空格或特殊字符。
接下来,createMetaphorfile为新隐喻搅动了一个特殊的模板。该模板具有一些标题的占位符,作者,创建了比喻的日期,语言和内容。这就像新故事的蓝图。
然后,createMetaphorfile淘汰了另一个称为“降低”的咒语。通过用问题数据中的相应值替换每个占位符,这有助于填充模板的空白。这就像用旧颜色从旧图片上画一张新图片。
之后,createMetaphorFile再使用一个咒语将完整的模板转换为一个时髦的,计算机友好的代码,称为“ base64”。此代码就像是只有计算机能理解的秘密语言。
最后,createMetaphorFile使用其github魔法在存储库中创建一个全新的文件。它根据slugified标题为文件提供了一个很酷的名称,并将完成的模板以base64格式在文件中作为内容。
和那样,createMetaphorFile使用github和javaScript的力量创建了一个新的隐喻。
2. createFileContent
功能
/**
* Creates or updates a file in a GitHub repository with the specified content.
* @async
* @function createFileContent
* @param {Object} options - An object containing options for the file creation/update operation.
* @param {string} options.owner - The owner of the GitHub repository.
* @param {string} options.repo - The name of the GitHub repository.
* @param {string} options.path - The path to the file in the repository.
* @param {string} options.message - The commit message to use for the file update/creation.
* @param {string} options.content - The content of the file to create/update, encoded in base64.
* @returns {Promise<Object>} A Promise that resolves with the metadata for the created/updated file.
*/
async function createFileContent({ client, owner, repo, path, message, content }) {
return await client.rest.repos.createOrUpdateFileContents({
owner,
repo,
path,
message,
content,
committer: {
name: ghBotUsername,
email: ghBotEmail
},
author: {
name: ghBotUsername,
email: ghBotEmail
}
});
}
因此,有一个称为“ CreateFileContent”的功能,完全点燃了!它用JavaScript编写,就像那里最酷的语言一样。
基本上,CreateFileContent就像一个使您与Github交谈的使者。它可以在github存储库中创建或更新文件,这就像一个大共享文件夹,很多人可以在项目上一起工作。
要使用CreateFileContent,您必须给它一些选项。这些选项就像说明createFileContent的说明。您需要告诉它,存储库的所有者是谁,存储库的名称是什么,在存储库中,您要放置该文件,提交的消息应该是什么,最重要的是,什么内容是什么文件应该是。
您给出了CreateFileContent所需的所有选项,便可以使用。它使用您指定的内容来创建或更新存储库中的文件。就这样,您的文件已保存并准备与世界共享!
完成createFileContent时,它会给您一些有关其创建或更新的文件的元数据。此元数据就像有关该文件的信息,例如上次更新时,谁更新了该文件以及文件的名称和路径是什么。
这样就可以了,CreateFileContent是一个完全寒冷的功能,可帮助您在github存储库中创建和更新文件,例如ð¶!
3. addLabelToClosedIssue
功能
/**
* Adds labels to a closed issue.
*
* @param {Object} client - The authenticated Octokit REST client.
* @param {string} owner - The owner of the repository.
* @param {string} repo - The name of the repository.
* @param {number} issue_number - The number of the issue to add labels to.
* @param {Array} [labels] - An array of labels to add to the issue.
* @returns {Promise<void>} A Promise that resolves when the labels have been added to the issue.
*/
async function addLabelToClosedIssue(client, owner, repo, issue_number, labels) {
await client.rest.issues.addLabels({
owner,
repo,
issue_number,
labels
})
console.log(`Label added: ${labels.join(', ')}`)
}
此代码是关于将标签添加到名为GitHub的网站上的封闭问题中。
当某人创建问题时,他们可以在其上添加标签以对其进行分类。有时候,问题会被关闭,但您可能仍然想向他们添加标签,以帮助人们以后找到它们。这就是该代码的作用!
代码收集了四个信息:存储库的所有者(类似于项目的老板),存储库的名称(项目居住的地方),问题的数量(如用于的代码问题),以及可选的标签以添加到该问题中。
然后,代码使用称为“ Addlabels”的魔术咒语将标签添加到该问题中。完成后,它说“添加了标签”和添加的标签名称。
总的来说,此代码就像在您已经完成阅读的书中添加贴纸一样,因此,当您以后想再次找到它时,您可以查找贴纸!
感谢@mkubdev
完整的隐喻故事
StreetCommunityProgrammer / action-collections
这是SCP Action Collections的存储库
SCP Action Collections
This is repository of SCP Action Collections