نظرات مطالب
آشنایی با ساختار یک Pull Request خوب
چگونه تمام تغییرات یک PR حجیم را از GitHub دانلود (بدون Merge آن) و به صورت محلی بررسی کنیم؟
ابتدا در برگهی Commits، آخرین Commit انجام شده را پیدا کنید (ممکن است بیش از یک مورد باشند؛ بنابراین آخرین مورد را در لیست انتخاب کنید):
سپس بر روی دکمهی <> آن کلیک نمائید تا کل مخزن کد را در این نقطهی از زمان نمایش دهد:
اکنون میتوانید این مخزن کد شبیه سازی شده را همانند سایر مخزنهای کد دریافت کنید.
ابتدا در برگهی Commits، آخرین Commit انجام شده را پیدا کنید (ممکن است بیش از یک مورد باشند؛ بنابراین آخرین مورد را در لیست انتخاب کنید):
سپس بر روی دکمهی <> آن کلیک نمائید تا کل مخزن کد را در این نقطهی از زمان نمایش دهد:
اکنون میتوانید این مخزن کد شبیه سازی شده را همانند سایر مخزنهای کد دریافت کنید.
GitHub Actions، یک راهحل Continuous Integration است که توسط آن میتوان یکسری trigger workflowهایی را حین push کردن، ارسال PR و … اجرا کرد. برای کارهایی از قبیل اجرای تستهای خودکار، اجرای یکسری تست و همچنین deploy کردن از آن استفاده میشود. GitHub Actions در واقع یک managed serviceیی است که توسط GitHub ارائه میشود. به این معنا که نیازی نیست خودمان درگیر مدیریت منابع باشیم. همچنین تعداد زیادی اکشن توسط community برای استفاده توسعه داده شدهاند. در ادامه ابتدا مرور سریعی بر GitHub Actions خواهیم داشت، سپس یک مثال از آن را به همراه PowerShell بررسی خواهیم کرد.
ساختار یک اکشن
- Workflow: یکی از مفاهیمی که باید با آن آشنا باشیم workflowها هستند. یک workflow مجموعهایی از jobهایی هستند که در رخدادهای خاصی اجرا میشوند. در واقع یک workflow یک CI pipeline است که با کمک YAML آنها را تعریف میکنیم.
- Runner: اینها به اصطلاح compute machineهایی هستند که workflowها را اجرا میکنند. این runnerها هم میتوانند به صورت سفارشی باشند و هم سرویسهای ارائه شده توسط GitHub باشند.
- Job: مجموعهایی از مراحلی که درون یک runner workspace اجرا میشوند.
- Step: در نهایت stepها هستند که کوچکترین بخش GitHub Actions هستند. stepها میتوانند فایل اسکریپت، Dockerfile یا یک community action باشند.
نمونهی یک Workflow
در ادامه یک workflow را مشاهده میکنید. در اینجا نام آن را به Build Application Code تنظیم کردهایم. سپس با کمک on، تریگر اجرای این workflow را تعیین کردهایم. به این معنا که با push کردن بر روی ریپوزیتوری، workflow اجرا خواهد شد. سپس توسط job، لیست jobهایی را که میخواهیم این workflow اجرا کند، مشخص کردهایم. اولین jobی که اجرا خواهد شد، build است. این job قرار است بر روی یک ماشین با آخرین نگارش ابونتو اجرا شود. مراحل یا stepهای این job نیز به ترتیب، clone کردن سورسکد و سپس نصب وابستگیهای پروژه است. در نهایت job بعدی، test خواهد بود که با کمک needs تعیین کردهایم که ابتدا مرحلهی قبل یعنی build اجرا شود و سپس وارد این مرحله شود.
name: Build Application Code on: [push] jobs: build: runs-on: ubuntu-latest steps: - name: Check out code uses: actions/checkout@v2 - name: Install Libraries uses: pip install -r requirements.txt -t . test: runs-on: ubuntu-latest needs: build steps: ...
مثال PowerShell
هدف، پویا کردن قسمت README یک پروفایل GitHub است. برای این مثال من از پروفایل خودم استفاده خواهم کرد. درون فایل README میخواهم لیست آخرین بلاگپستهایی را که منتشر کردهام، به همراه یک کامپوننت، تعداد قدمهایی را که در طول روز پیادهروی میکنم، نمایش دهم. برای نمایش آخرین دیتای درون پروفایلم، نیاز به دو Action Workflow داشتیم که هر یک در تایم خاصی اجرا شده و اسکریپتهایی را که در ادامه توضیح خواهم داد، اجرا کنند. برای اینکار درون دایرکتوری مخصوص github.، ساختار زیر را ایجاد کردهام:
├── .github │ ├── scripts │ └── workflows ├── README.md ├── assets └── deps
name: Update Recent Blog Posts on: schedule: - cron: "0 0 * * 0" # Run once a week at 00:00 (midnight) on Sunday workflow_dispatch: jobs: update_posts: runs-on: ubuntu-latest steps: - name: Check out repository code uses: actions/checkout@v3 - name: Run the script for fetching latest blog posts shell: pwsh run: | . ./.github/scripts/Get-Posts.ps1 - name: Commit and Push the changes uses: mikeal/publish-to-github-action@master env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Function Get-Posts { Param ( [Parameter(Mandatory = $false)] [string]$rssUrl ) $posts = @() $feed = [xml](Invoke-WebRequest -Uri $rssUrl).Content $feed.rss.channel.item | Select-Object -First 3 | ForEach-Object { $post = [PSCustomObject]@{ Title = $_.title."#cdata-section" ?? $_.title Link = $_.link Description = $_.description."#cdata-section" ?? $_.description PubDate = $_.pubDate } $posts += $post } $posts } Function Get-DntipsPosts { $assemblyPath = "$(Get-Location)/deps/CodeHollow.FeedReader.dll" [Reflection.Assembly]::LoadFile($assemblyPath) $feed = [CodeHollow.FeedReader.FeedReader]::ReadAsync("https://www.dntips.ir/feed/author/%d8%b3%db%8c%d8%b1%d9%88%d8%a7%d9%86%20%d8%b9%d9%81%db%8c%d9%81%db%8c").Result $posts = @() $feed.Items | Select-Object -First 3 | ForEach-Object { $post = [PSCustomObject]@{ Title = $_.Title Link = $_.Link Description = $_.Description PubDate = $_.PublishingDate } $posts += $post } $posts } Function Set-Posts { [CmdletBinding()] Param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [PSCustomObject[]]$posts, [Parameter(Mandatory = $false)] [string]$marker = "## Recent Blog Posts - English" ) Begin { $readMePath = "./README.md" $readmeContents = Get-Content -Path $readMePath -Raw $markdownTable = "| Link | Published At |`n" $markdownTable += "| --- | --- |`n" } Process { if ($null -eq $_.Title) { return } $date = Get-Date -Date $_.PubDate $link = "[$($_.Title)]($($_.Link))" $markdownTable += "| $($link) | $($date.ToString("dd/MM/yy")) |`n" } End { $updatedContent = $readmeContents -replace "$marker\n([\s\S]*?)(?=#| $)", "$marker`n$($markdownTable)`n" $updatedContent | Set-Content -Path $readMePath } } Function Set-Blogs { $recentBlogPostsStr = "## Recent blog posts -" Get-Posts("https://dev.to/feed/sirwanafifi") | Set-Posts -marker "$recentBlogPostsStr dev.to" Get-Posts("https://sirwan.infohttps://www.dntips.ir/rss.xml") | Set-Posts -marker "$recentBlogPostsStr sirwan.info" Get-DntipsPosts | Set-Posts -marker "$recentBlogPostsStr dntips.ir" } Set-Blogs
در اینجا تابع Set-Blogs فراخوانی خواهد شد. کاری که این تابع انجام میدهد، دریافت آخرین بلاگپستهایی که در جاهای مختلف منتشر کردهام و سپس آپدیت کردن فایل README با دیتای جدید است. همانطور که مشاهده میکنید برای خواندن فید سایت جاری، از پکیج FeedReader استفاده کردهام. در PowerShell توسط Invoke-WebRequest میتوانیم یک فید را پارز کنیم؛ اما برای سایت جاری با خطا روبرو شدم و در نهایت تصمیم گرفتم از یک پکیج داتنتی استفاده کنم. وابستگی موردنظر، درون دایرکتوری dep به صورت DLL قرار دارد. سپس از طریق PowerShell اسمبلی مربوطه بارگذاری شده و از کتابخانه موردنظر استفاده شدهاست. در نهایت برای آپدیت کردن فایل README.md یکسری marker تعیین کردهام که با یک جایگزینی محتویات موردنظر، آنجا قرار خواهند گرفت.
workflow بعدی نیز به صورت زیر میباشد که در پایان هر روز در یک ساعت مشخص اجرا خواهد شد:
name: Update Step Component on: schedule: - cron: "0 18 * * *" workflow_dispatch: jobs: update_steps: runs-on: ubuntu-latest steps: - name: Check out repository code uses: actions/checkout@v3 - name: Run the script for fetching my latest steps shell: pwsh env: STEPS_URI: ${{ secrets.STEPS_URI }} run: | . ./.github/scripts/Get-Steps.ps1 - name: Commit and Push the changes uses: mikeal/publish-to-github-action@master env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Function Set-Steps { Param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [PSObject]$json ) Write-Host ($json | ConvertTo-Json) $SvgPath = "$(Get-Location)/assets/step.svg" $SvgContent = Get-Content -Path $SvgPath -Raw $TextTags = @" <tspan id="step-count" font-weight="bold">$([System.String]::Format("{0:n0}", [int]$json.steps))</tspan> "@ $DatetimeTags = "<text id=""datetime"" x=""800"" y=""72"" font-size=""39"" fill="#99989E"">$($json.date)</text>" $SvgContent = $SvgContent -Replace '<tspan id="step-count" font-weight="bold">.*?</tspan>', $TextTags $SvgContent = $SvgContent -Replace '<text id="datetime" x="800" y="72" font-size="39" fill="#99989E">.*?</text>', $DatetimeTags $SvgContent | Set-Content -Path $SvgPath } Function Get-LatestSteps { Try { $Uri = $env:STEPS_URI Write-Host "Uri: $Uri" $JsonResult = (Invoke-WebRequest -Uri $Uri).Content | ConvertFrom-Json Write-Host "Steps: $($JsonResult.steps)" Return $JsonResult } Catch { Return @{ steps = 0 date = Get-Date -Format "yyyy-MM-dd" } } } Write-Host "Getting latest steps..." Get-LatestSteps | Set-Steps Write-Host "Done!"
خروجی در نهایت، اینچنین خواهد بود:
اشتراکها
دوره آموزشی Blazor از مایکروسافت
اشتراکها
تم تیره (Dark) برای Github
اشتراکها