Kurz: Vytvoření akce GitHubu pomocí .NET
Zjistěte, jak vytvořit aplikaci .NET, která se dá použít jako akce GitHubu. GitHub Actions umožňuje automatizaci a složení pracovních postupů. Pomocí GitHub Actions můžete vytvářet, testovat a nasazovat zdrojový kód z GitHubu. Akce navíc zpřístupňují možnost programově pracovat s problémy, vytvářet žádosti o přijetí změn, provádět kontroly kódu a spravovat větve. Další informace o kontinuální integraci s GitHub Actions najdete v tématu Sestavování a testování .NET.
V tomto kurzu se naučíte:
- Příprava aplikace .NET pro GitHub Actions
- Definování vstupů a výstupů akcí
- Vytvoření pracovního postupu
Požadavky
- Účet GitHub
- Sada .NET 6 SDK nebo novější
- Integrované vývojové prostředí .NET (IDE)
- Neváhejte používat integrované vývojové prostředí sady Visual Studio
Záměr aplikace
Aplikace v tomto kurzu provádí analýzu metrik kódu pomocí:
Skenování a zjišťování souborů projektu *.csproj a *.vbproj .
Analýza zjištěného zdrojového kódu v rámci těchto projektů pro:
- Cyklomaticová složitost
- Index udržovatelnosti
- Hloubka dědičnosti
- Párování tříd
- Počet řádků zdrojového kódu
- Přibližné řádky spustitelného kódu
Vytvoření (nebo aktualizace) souboru CODE_METRICS.md
Aplikace neodpovídá za vytvoření žádosti o přijetí změn se změnami souboru CODE_METRICS.md. Tyto změny se spravují jako součást složení pracovního postupu.
Odkazy na zdrojový kód v tomto kurzu obsahují části aplikace, které jsou pro stručnost vynechány. Kompletní kód aplikace je k dispozici na GitHubu.
Prozkoumat aplikaci
Konzolová aplikace .NET používá CommandLineParser
balíček NuGet k analýze argumentů do objektu ActionInputs
.
using CommandLine;
namespace DotNet.GitHubAction;
public class ActionInputs
{
string _repositoryName = null!;
string _branchName = null!;
public ActionInputs()
{
if (Environment.GetEnvironmentVariable("GREETINGS") is { Length: > 0 } greetings)
{
Console.WriteLine(greetings);
}
}
[Option('o', "owner",
Required = true,
HelpText = "The owner, for example: \"dotnet\". Assign from `github.repository_owner`.")]
public string Owner { get; set; } = null!;
[Option('n', "name",
Required = true,
HelpText = "The repository name, for example: \"samples\". Assign from `github.repository`.")]
public string Name
{
get => _repositoryName;
set => ParseAndAssign(value, str => _repositoryName = str);
}
[Option('b', "branch",
Required = true,
HelpText = "The branch name, for example: \"refs/heads/main\". Assign from `github.ref`.")]
public string Branch
{
get => _branchName;
set => ParseAndAssign(value, str => _branchName = str);
}
[Option('d', "dir",
Required = true,
HelpText = "The root directory to start recursive searching from.")]
public string Directory { get; set; } = null!;
[Option('w', "workspace",
Required = true,
HelpText = "The workspace directory, or repository root directory.")]
public string WorkspaceDirectory { get; set; } = null!;
static void ParseAndAssign(string? value, Action<string> assign)
{
if (value is { Length: > 0 } && assign is not null)
{
assign(value.Split("/")[^1]);
}
}
}
Předchozí třída vstupů akcí definuje několik požadovaných vstupů pro úspěšné spuštění aplikace. Konstruktor zapíše "GREETINGS"
hodnotu proměnné prostředí, pokud je k dispozici v aktuálním spouštěcím prostředí. Branch
Vlastnosti Name
se analyzují a přiřazují z posledního "/"
segmentu řetězce s oddělovači.
S definovanou třídou vstupů akcí se zaměřte na soubor Program.cs .
using System.Text;
using CommandLine;
using DotNet.GitHubAction;
using DotNet.GitHubAction.Extensions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using static CommandLine.Parser;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddGitHubActionServices();
using IHost host = builder.Build();
ParserResult<ActionInputs> parser = Default.ParseArguments<ActionInputs>(() => new(), args);
parser.WithNotParsed(
errors =>
{
host.Services
.GetRequiredService<ILoggerFactory>()
.CreateLogger("DotNet.GitHubAction.Program")
.LogError("{Errors}", string.Join(
Environment.NewLine, errors.Select(error => error.ToString())));
Environment.Exit(2);
});
await parser.WithParsedAsync(
async options => await StartAnalysisAsync(options, host));
await host.RunAsync();
static async ValueTask StartAnalysisAsync(ActionInputs inputs, IHost host)
{
// Omitted for brevity, here is the pseudo code:
// - Read projects
// - Calculate code metric analytics
// - Write the CODE_METRICS.md file
// - Set the outputs
var updatedMetrics = true;
var title = "Updated 2 projects";
var summary = "Calculated code metrics on two projects.";
// Do the work here...
// Write GitHub Action workflow outputs.
var gitHubOutputFile = Environment.GetEnvironmentVariable("GITHUB_OUTPUT");
if (!string.IsNullOrWhiteSpace(gitHubOutputFile))
{
using StreamWriter textWriter = new(gitHubOutputFile, true, Encoding.UTF8);
textWriter.WriteLine($"updated-metrics={updatedMetrics}");
textWriter.WriteLine($"summary-title={title}");
textWriter.WriteLine($"summary-details={summary}");
}
await ValueTask.CompletedTask;
Environment.Exit(0);
}
Soubor Program
je zjednodušený pro stručnost, abyste prozkoumali úplný ukázkový zdroj, viz Program.cs. Tato mechanika demonstruje často používaný kód potřebný k použití:
Odkazy na externí projekt nebo balíček lze použít a zaregistrovat pomocí injektáže závislostí. Jedná se Get<TService>
o statickou místní funkci, která vyžaduje IHost
instanci a slouží k vyřešení požadovaných služeb. CommandLine.Parser.Default
S singletonem získá parser
aplikace instanci z objektu args
. Pokud argumenty nelze analyzovat, aplikace se ukončí nenulovým ukončovacím kódem. Další informace naleznete v tématu Nastavení ukončovací kódy pro akce.
Když se args úspěšně parsují, aplikace byla volána správně s požadovanými vstupy. V tomto případě se provede volání primární funkce StartAnalysisAsync
.
Pokud chcete zapisovat výstupní hodnoty, musíte postupovat podle formátu, který GitHub Actions rozpozná: Nastavení výstupního parametru.
Příprava aplikace .NET pro GitHub Actions
GitHub Actions podporuje dvě varianty vývoje aplikací, a to buď
- JavaScript (volitelně TypeScript)
- Kontejner Dockeru (libovolná aplikace, která běží v Dockeru)
Virtuální prostředí, ve kterém je akce GitHubu hostovaná, může nebo nemusí mít nainstalovanou technologii .NET. Informace o tom, co je předinstalované v cílovém prostředí, najdete v tématu Virtuální prostředí GitHub Actions. I když je možné spouštět příkazy rozhraní příkazového řádku .NET z pracovních postupů GitHub Actions, aby bylo možné plně fungovat . Akci GitHubu založenou na technologii NET doporučujeme, abyste aplikaci kontejnerizovali. Další informace najdete v tématu Kontejnerizace aplikace .NET.
Soubor Dockerfile
Soubor Dockerfile je sada instrukcí pro sestavení image. V případě aplikací .NET se soubor Dockerfile obvykle nachází v kořenovém adresáři vedle souboru řešení.
# Set the base image as the .NET 7.0 SDK (this includes the runtime)
FROM mcr.microsoft.com/dotnet/sdk:7.0@sha256:d32bd65cf5843f413e81f5d917057c82da99737cb1637e905a1a4bc2e7ec6c8d as build-env
# Copy everything and publish the release (publish implicitly restores and builds)
WORKDIR /app
COPY . ./
RUN dotnet publish ./DotNet.GitHubAction/DotNet.GitHubAction.csproj -c Release -o out --no-self-contained
# Label the container
LABEL maintainer="David Pine <david.pine@microsoft.com>"
LABEL repository="https://github.com/dotnet/samples"
LABEL homepage="https://github.com/dotnet/samples"
# Label as GitHub action
LABEL com.github.actions.name="The name of your GitHub Action"
# Limit to 160 characters
LABEL com.github.actions.description="The description of your GitHub Action."
# See branding:
# https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#branding
LABEL com.github.actions.icon="activity"
LABEL com.github.actions.color="orange"
# Relayer the .NET SDK, anew with the build output
FROM mcr.microsoft.com/dotnet/sdk:7.0@sha256:d32bd65cf5843f413e81f5d917057c82da99737cb1637e905a1a4bc2e7ec6c8d
COPY --from=build-env /app/out .
ENTRYPOINT [ "dotnet", "/DotNet.GitHubAction.dll" ]
Poznámka:
Aplikace .NET v tomto kurzu spoléhá na sadu .NET SDK jako součást jeho funkcí. Soubor Dockerfile vytvoří novou sadu vrstev Dockeru nezávisle na předchozích vrstvách. Začíná úplně od začátku s imagí sady SDK a přidá výstup sestavení z předchozí sady vrstev. U aplikací, které nevyžadují sadu .NET SDK jako součást jejich funkcí, by se místo toho měly spoléhat pouze na modul runtime .NET. Tím se výrazně zmenšuje velikost obrázku.
FROM mcr.microsoft.com/dotnet/runtime:7.0
Upozorňující
Věnujte pozornost každému kroku v souboru Dockerfile, protože se liší od standardního souboru Dockerfile vytvořeného z funkce "přidání podpory Dockeru". Konkrétně se poslední několik kroků liší tím, že nezadáte novou WORKDIR
, která by změnila cestu k aplikaci ENTRYPOINT
.
Mezi předchozí kroky souboru Dockerfile patří:
- Nastavení základní image z
mcr.microsoft.com/dotnet/sdk:7.0
aliasubuild-env
. - Kopírování obsahu a publikování aplikace .NET:
- Aplikace se publikuje pomocí
dotnet publish
příkazu.
- Aplikace se publikuje pomocí
- Použití popisků v kontejneru
- Přenos image sady .NET SDK z
mcr.microsoft.com/dotnet/sdk:7.0
- Kopírování publikovaného výstupu sestavení z objektu
build-env
. - Definování vstupního bodu, na který delegáti .
dotnet /DotNet.GitHubAction.dll
Tip
MCR mcr.microsoft.com
je zkratka pro Microsoft Container Registry a je syndikovaný katalog kontejnerů Microsoftu z oficiálního centra Dockeru. Další informace naleznete v tématu Syndikáty katalogu kontejnerů Společnosti Microsoft.
Upozornění
Pokud k připnutí verze sady SDK použijete soubor global.json , měli byste explicitně odkazovat na tuto verzi v souboru Dockerfile. Pokud jste například ke připnutí verze sady SDK použili soubor global.json, měl by váš soubor Dockerfile použít mcr.microsoft.com/dotnet/sdk:5.0.300
.5.0.300
Tím se zabrání porušení GitHub Actions při vydání nové dílčí revize.
Definování vstupů a výstupů akcí
V části Prozkoumat aplikaci jste se dozvěděli o ActionInputs
třídě. Tento objekt představuje vstupy akce GitHubu. Aby GitHub rozpoznal, že úložiště je akce GitHubu, musíte mít soubor action.yml v kořenovém adresáři úložiště.
name: 'The title of your GitHub Action'
description: 'The description of your GitHub Action'
branding:
icon: activity
color: orange
inputs:
owner:
description:
'The owner of the repo. Assign from github.repository_owner. Example, "dotnet".'
required: true
name:
description:
'The repository name. Example, "samples".'
required: true
branch:
description:
'The branch name. Assign from github.ref. Example, "refs/heads/main".'
required: true
dir:
description:
'The root directory to work from. Examples, "path/to/code".'
required: false
default: '/github/workspace'
outputs:
summary-title:
description:
'The title of the code metrics action.'
summary-details:
description:
'A detailed summary of all the projects that were flagged.'
updated-metrics:
description:
'A boolean value, indicating whether or not the action updated metrics.'
runs:
using: 'docker'
image: 'Dockerfile'
args:
- '-o'
- ${{ inputs.owner }}
- '-n'
- ${{ inputs.name }}
- '-b'
- ${{ inputs.branch }}
- '-d'
- ${{ inputs.dir }}
Předchozí soubor action.yml definuje:
- Akce GitHubu
name
adescription
akce GitHubu - Nástroj
branding
, který se používá na GitHub Marketplace k jedinečnější identifikaci vaší akce - ,
inputs
který mapuje 1:1 sActionInputs
třídou - ,
outputs
který je zapsán doProgram
a používá se jako součást složení pracovního postupu - Uzel
runs
, který GitHubu říká, že aplikace jedocker
aplikace a jaké argumenty se mají předat do ní
Další informace najdete v tématu Syntaxe metadat pro GitHub Actions.
Předdefinované proměnné prostředí
Pomocí GitHub Actions získáte ve výchozím nastavení spoustu proměnných prostředí. Proměnná GITHUB_REF
bude například vždy obsahovat odkaz na větev nebo značku, která aktivovala spuštění pracovního postupu. GITHUB_REPOSITORY
má například název dotnet/docs
vlastníka a úložiště .
Měli byste prozkoumat předem definované proměnné prostředí a odpovídajícím způsobem je používat.
Složení pracovního postupu
S kontejnerizovaným aplikací .NET a definovanými vstupy a výstupy akcí můžete akci využívat. Aby bylo možné gitHub Actions použít, není nutné publikovat na GitHub Marketplace. Pracovní postupy se definují v adresáři .github/workflows úložiště jako soubory YAML.
# The name of the work flow. Badges will use this name
name: '.NET code metrics'
on:
push:
branches: [ main ]
paths:
- 'github-actions/DotNet.GitHubAction/**' # run on all changes to this dir
- '!github-actions/DotNet.GitHubAction/CODE_METRICS.md' # ignore this file
workflow_dispatch:
inputs:
reason:
description: 'The reason for running the workflow'
required: true
default: 'Manual run'
jobs:
analysis:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v3
- name: 'Print manual run reason'
if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
echo 'Reason: ${{ github.event.inputs.reason }}'
- name: .NET code metrics
id: dotnet-code-metrics
uses: dotnet/samples/github-actions/DotNet.GitHubAction@main
env:
GREETINGS: 'Hello, .NET developers!' # ${{ secrets.GITHUB_TOKEN }}
with:
owner: ${{ github.repository_owner }}
name: ${{ github.repository }}
branch: ${{ github.ref }}
dir: ${{ './github-actions/DotNet.GitHubAction' }}
- name: Create pull request
uses: peter-evans/create-pull-request@v4
if: ${{ steps.dotnet-code-metrics.outputs.updated-metrics }} == 'true'
with:
title: '${{ steps.dotnet-code-metrics.outputs.summary-title }}'
body: '${{ steps.dotnet-code-metrics.outputs.summary-details }}'
commit-message: '.NET code metrics, automated pull request.'
Důležité
Pro kontejnerizované GitHub Actions musíte použít runs-on: ubuntu-latest
. Další informace naleznete v tématu Syntaxe jobs.<job_id>.runs-on
pracovního postupu .
Předchozí soubor YAML pracovního postupu definuje tři primární uzly:
- Pracovní
name
postup. Tento název se také používá při vytváření odznáček stavu pracovního postupu. - Uzel
on
definuje, kdy a jak se akce aktivuje. - Uzel
jobs
popisuje různé úlohy a kroky v rámci každé úlohy. Jednotlivé kroky využívají GitHub Actions.
Další informace naleznete v tématu Vytvoření prvního pracovního postupu.
Zaměření na steps
uzel, složení je jasnější:
steps:
- uses: actions/checkout@v3
- name: 'Print manual run reason'
if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
echo 'Reason: ${{ github.event.inputs.reason }}'
- name: .NET code metrics
id: dotnet-code-metrics
uses: dotnet/samples/github-actions/DotNet.GitHubAction@main
env:
GREETINGS: 'Hello, .NET developers!' # ${{ secrets.GITHUB_TOKEN }}
with:
owner: ${{ github.repository_owner }}
name: ${{ github.repository }}
branch: ${{ github.ref }}
dir: ${{ './github-actions/DotNet.GitHubAction' }}
- name: Create pull request
uses: peter-evans/create-pull-request@v4
if: ${{ steps.dotnet-code-metrics.outputs.updated-metrics }} == 'true'
with:
title: '${{ steps.dotnet-code-metrics.outputs.summary-title }}'
body: '${{ steps.dotnet-code-metrics.outputs.summary-details }}'
commit-message: '.NET code metrics, automated pull request.'
Představuje jobs.steps
složení pracovního postupu. Kroky jsou orchestrovány tak, aby byly sekvenční, komunikační a kompozibilní. S různými akcemi GitHub Actions představujícími kroky se dají skládat pracovní postupy, které mají vstupy a výstupy.
V předchozích krocích můžete sledovat:
Úložiště je rezervováno.
Při ručním spuštění se do protokolu pracovního postupu vytiskne zpráva.
Krok označený jako
dotnet-code-metrics
:uses: dotnet/samples/github-actions/DotNet.GitHubAction@main
je umístění kontejnerizované aplikace .NET v tomto kurzu.env
vytvoří proměnnou"GREETING"
prostředí, která se vytiskne při provádění aplikace.with
určuje každý z požadovaných vstupů akce.
Podmíněný krok s názvem
Create pull request
se spustí, kdyždotnet-code-metrics
krok určuje výstupní parametrupdated-metrics
s hodnotoutrue
.
Důležité
GitHub umožňuje vytvářet šifrované tajné kódy. Tajné kódy lze použít v rámci složení pracovního postupu pomocí ${{ secrets.SECRET_NAME }}
syntaxe. V kontextu akce GitHubu existuje token GitHubu, který se ve výchozím nastavení automaticky vyplní: ${{ secrets.GITHUB_TOKEN }}
. Další informace najdete v tématu Kontextová syntaxe a syntaxe výrazů pro GitHub Actions.
Spojení všech součástí dohromady
Úložiště dotnet/samples GitHubu je domovem mnoha projektů zdrojového kódu .NET, včetně aplikace v tomto kurzu.
Vygenerovaný soubor CODE_METRICS.md je možné procházet. Tento soubor představuje hierarchii projektů, které analyzoval. Každý projekt má oddíl nejvyšší úrovně a emoji, který představuje celkový stav nejvyšší složitosti cyklomatické pro vnořené objekty. Při procházení souboru každá část zveřejňuje příležitosti přechodu k podrobnostem se souhrnem jednotlivých oblastí. Markdown obsahuje sbalitelné oddíly jako další pohodlí.
Hierarchie postupuje od:
- Soubor projektu do sestavení
- Sestavení do oboru názvů
- Obor názvů pro pojmenovaný typ
- Každý pojmenovaný typ má tabulku a každá tabulka má:
- Odkazy na čísla řádků pro pole, metody a vlastnosti
- Individuální hodnocení metrik kódu
V praxi
Pracovní postup určuje, že on
push
main
větev se aktivuje ke spuštění akce. Když se spustí, na kartě Akce na GitHubu se nahlásí stream živého protokolu spuštění. Tady je příklad protokolu ze .NET code metrics
spuštění:
Zlepšení výkonu
Pokud jste postupovali podle ukázky, možná jste si všimli, že při každém použití této akce provede sestavení Dockeru pro tuto image. Každá aktivační událost tedy čelí určité době sestavení kontejneru před jeho spuštěním. Než gitHub Actions vydáte na marketplace, měli byste:
- (automaticky) Sestavení image Dockeru
- Nasdílení image Dockeru do služby GitHub Container Registry (nebo jiného veřejného registru kontejneru)
- Změňte akci tak, aby se image nevytvořela, ale aby se používala image z veřejného registru.
# Rest of action.yml content removed for readability
# using Dockerfile
runs:
using: 'docker'
image: 'Dockerfile' # Change this line
# using container image from public registry
runs:
using: 'docker'
image: 'docker://ghcr.io/some-user/some-registry' # Starting with docker:// is important!!
Další informace najdete v dokumentaci GitHubu: Práce s registrem kontejneru.
Viz také
- Obecný hostitel .NET
- Injektáž závislostí v .NET
- Hodnoty metrik kódu
- Open source build GitHub Action v .NET s pracovním postupem pro sestavení a nasdílením image Dockeru automaticky.