برنامه نویسی

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();
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

علامت گذاری رندر شده به این صورت است:

خلاصه کار

خلاصه کار


امیدوارم این پست برای شما مفید بوده باشد. اگر سوال یا نظری دارید، در زیر آن را مطرح کنید. اگر می خواهید با من ارتباط برقرار کنید، می توانید من را در لینکدین یا گیت هاب پیدا کنید. با تشکر برای خواندن!

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا