AdaGPT: آموخته های من در حین ساخت یک اکشن GitHub
من چند روز پیش GitHub Action خود را، AdaGPT، برای Hackathon GitHub اینجا در DEV.to پست کردم. در حین اجرای این عمل، چیزهای زیادی یاد گرفتم و می خواهم برای به اشتراک گذاشتن آنها وقت بگذارم. در اینجا آموخته های من بدون ترتیب خاصی آمده است:
الگوهای اکشن
برای شروع سریع با یک عمل جاوا اسکریپت، توصیه می کنم از الگوهای رسمی GitHub برای جاوا اسکریپت و تایپ اسکریپت استفاده کنید.
انواع TypeScript
زندگی با انواع ایستا آسان تر است، حداقل برای من. اگر از TypeScript استفاده می کنید، GitHub آن را ارائه می دهد @octokit/webhooks-types
بسته با تعاریف رسمی نوع برای همه انواع رویدادهای وب هوک و بارهای GitHub.
این انواع برای یافتن اینکه چه داده هایی از بارگذاری رویداد موجود است و چه داده هایی باید با SDK خوانده شوند مفید هستند. به عنوان مثال issue_comment
رویداد برای created
اقدام حاوی این داده ها است:
export interface IssueCommentCreatedEvent {
action: "created";
/**
* The [issue](https://docs.github.com/en/rest/reference/issues) the comment belongs to.
*/
issue: Issue & {
assignee: User | null;
/**
* State of the issue; either 'open' or 'closed'
*/
state: "open" | "closed";
locked: boolean;
labels: Label[];
};
comment: IssueComment;
repository: Repository;
sender: User;
installation?: InstallationLite;
organization?: Organization;
}
مشتری Ocktokit
بسته @actions/github
یک سرویس گیرنده Octokit.js هیدراته ارائه می دهد. Octokit.js SDK GitHub است و شامل چندین زیر بسته مانند است @octokit/rest
و @octokit/graphql
برای تعامل با REST یا GraphQL API.
import * as core from '@actions/core';
import * as github from '@actions/github';
const token = core.getInput('github_token');
const octokit = github.getOctokit(token)
const { data: diff } = await octokit.rest.pulls.get({
owner: 'octokit',
repo: 'rest.js',
pull_number: 123,
mediaType: {
format: 'diff'
}
});
سرویس گیرنده REST API برای جاوا اسکریپت دارای اسناد گسترده با نمونه های کد بسیاری است.
زمینه GitHub
بسته @actions/github
هیدراته را فراهم می کند Context
از محیط گردش کار فعلی با اطلاعات مفید فراوان.
مخزن فعلی و شماره شماره را می توان به جای ارائه آنها از طریق یک ورودی یا خواندن آنها از یک متغیر محیطی، مستقیماً از متن بازیابی کرد:
import * as core from '@actions/core'
import * as github from '@actions/github'
// get issue number from input
const issue = core.getInput('issue_number');
// get repository from environment
const [owner, repo] = (process.env.GITHUB_REPOSITORY || '').split('/');
//---------------------------------------------------------
// get issue number and repository from context
const issue = github.context.issue.number;
const { owner, repo } = github.context.repo;
نظرات در مورد مسائل و درخواست های کششی
را issue_comment
رویداد برای نظرات در مورد هر دو موضوع رخ می دهد و درخواست های کششی با این حال، میتوانید از بررسی شرطی در تعریف گردش کار برای تمایز بین مسائل و درخواستهای کششی استفاده کنید:
on: issue_comment
jobs:
pr_commented:
# This job only runs for pull request comments
name: PR comment
if: ${{ github.event.issue.pull_request }}
runs-on: ubuntu-latest
steps:
- run: |
echo A comment on PR $NUMBER
env:
NUMBER: ${{ github.event.issue.number }}
issue_commented:
# This job only runs for issue comments
name: Issue comment
if: ${{ !github.event.issue.pull_request }}
runs-on: ubuntu-latest
steps:
- run: |
echo A comment on issue $NUMBER
env:
NUMBER: ${{ github.event.issue.number }}
همین تمایز را می توان در داخل عمل با زمینه ایجاد کرد:
import * as core from '@actions/core'
import * as github from '@actions/github'
// is comment on issue
const isIssueComment = github.context.eventName === 'issue_comment' && github.context.payload.issue?.pull_request === undefined;
// is comment on pull request
const isPullRequestComment = github.context.eventName === 'issue_comment' && github.context.payload.issue?.pull_request !== undefined;
Action Locally را اجرا کنید
می توانید استفاده کنید act
بسته ای برای اجرای گردش کار و عملکرد خود به صورت محلی، بنابراین لازم نیست هر بار که می خواهید تغییرات را آزمایش کنید، متعهد شوید و فشار دهید. واقعاً خوب کار می کند و به شما کمک می کند تا خیلی سریعتر پیشرفت کنید.
اگر گردش کار را به صورت محلی اجرا کنید، یک توکن GitHub خودکار برای تعامل با REST API دریافت نخواهید کرد. این بدان معنی است که شما باید یک رمز دسترسی شخصی ایجاد کنید و این توکن را به عنوان ارائه دهید GITHUB_TOKEN
برای اجرای گردش کار من ایجاد یک محلی را توصیه می کنم .env
فایل با PAT خود:
# file: .env
GITHUB_TOKEN=<personal-access-token>
این فایل مخفی را می توان به act
هنگام اجرا به صورت محلی:
act issue_comment --secret-file .env
طبق معمول، توکن در گردش کار از طریق سینتکس در دسترس است ${ secrets.GITHUB_TOKEN }}
.
صفحه بندی
REST API صفحه بندی شده است و تا 100 مورد را در هر صفحه برمی گرداند. میتوانید از Pagination API برای خواندن همه موارد یک نقطه پایانی خاص استفاده کنید:
import * as core from '@actions/core'
import * as github from '@actions/github'
import type { Issue } from '@octokit/webhooks-types';
const token = core.getInput('github_token');
const { owner, repo } = github.context.repo;
const octokit = github.getOctokit(token);
const issues: Issue[] = await octokit.paginate(octokit.rest.issues.listForRepo, {
owner,
repo,
per_page: 100,
});
خلاصه کار بنویسید
Job Summary یک فایل علامت گذاری با نتایج مشاغل در یک گردش کار است. این پست وبلاگ از GitHub نمای کلی خوبی ارائه می دهد.
به عنوان مثال، من این خلاصه کار را برای GitHub Action خود می نویسم:
import * as core from '@actions/core'
import * as github from '@actions/github'
await core.summary
.addLink('Issue', issue.html_url)
.addHeading('Request', 3)
.addRaw(request.body ?? '', true)
.addBreak()
.addLink('Comment', request.html_url)
.addHeading('Response', 3)
.addRaw(response.body ?? '', true)
.addBreak()
.addLink('Comment', response.html_url)
.addBreak()
.addHeading('GitHub Context', 3)
.addCodeBlock(JSON.stringify(github.context.payload, null, 2), 'json')
.write();
علامت گذاری رندر شده به این صورت است:
امیدوارم این پست برای شما مفید بوده باشد. اگر سوال یا نظری دارید، در زیر آن را مطرح کنید. اگر می خواهید با من ارتباط برقرار کنید، می توانید من را در لینکدین یا گیت هاب پیدا کنید. با تشکر برای خواندن!