GitHub Action .NET AOT monialustajulkaisuille

Published on Thursday, April 2, 2026

GitHub Action .NET AOT monialustajulkaisuille

.NET:in 8-versiossa mukaan tuli natiivi ahead-of-time (AOT) -tuki, jonka avulla on mahdollista toteuttaa tavallisia ajettavia binäärejä omista .NET-sovelluksista. Joskus saattaa olla tarpeellista julkaista tällainen sovellus tällä tavalla mahdollisimman monelle eri käyttöjärjestelmälle, ja itse päädyin toteuttamaan kääntämiset + julkaisut GitHub Actionin avulla.

Koodi

Alla yaml-koodi kokonaisuudessaan ja lisäksi tarkennan muutamaa kohtaa erillisissä tekstiosioissa

# This workflow will build AOT CLI for all supported systems

name: .NET publish cli

on:
  push:
     tags:
      - cli-*
  workflow_dispatch:

jobs:
  buildaots:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [windows-latest, macos-latest, ubuntu-latest]
    steps:
    - uses: actions/checkout@v6
    - name: Setup .NET
      uses: actions/setup-dotnet@v5
      with:
        dotnet-version: 10.0.x

    - name: Publish Windows x64
      run: dotnet publish -r win-x64 -c Release -o win-x64
      working-directory: cli
      if: matrix.os == 'windows-latest'
    - uses: actions/upload-artifact@v6
      if: matrix.os == 'windows-latest'
      with:
        name: codec8cli-win-x64
        path: cli/win-x64
        compression-level: 9 # maximum compression

    - name: Publish Linux x64
      run: dotnet publish -r linux-x64 -c Release -o linux-x64
      working-directory: cli
      if: matrix.os == 'ubuntu-latest'
    - uses: actions/upload-artifact@v6
      if: matrix.os == 'ubuntu-latest'
      with:
        name: codec8cli-linux-x64
        path: cli/linux-x64
        compression-level: 9 # maximum compression

    - name: Publish Mac arm64
      run: dotnet publish -r osx-arm64 -c Release -o osx-arm64
      working-directory: cli
      if: matrix.os == 'macos-latest'
    - uses: actions/upload-artifact@v6
      if: matrix.os == 'macos-latest'
      with:
        name: codec8cli-mac-arm64
        path: cli/osx-arm64
        compression-level: 9 # maximum compression

  releaseartifacts:
    runs-on: ubuntu-latest
    needs: buildaots
    steps:
      - uses: actions/download-artifact@v8
      - name: Display structure of downloaded files
        run: ls -R
      - name: Zip win-x64
        run: zip -9 -r ../codec8cli-win-x64.zip .
        working-directory: codec8cli-win-x64
      - name: Zip linux-x64
        run: zip -9 -r ../codec8cli-linux-x64.zip .
        working-directory: codec8cli-linux-x64
      - name: Zip mac-arm64
        run: zip -9 -r ../codec8cli-mac-arm64.zip .
        working-directory: codec8cli-mac-arm64
      - name: Release
        uses: softprops/action-gh-release@v2
        if: github.ref_type == 'tag'
        with:
          files: |
            codec8cli-win-x64.zip
            codec8cli-linux-x64.zip
            codec8cli-mac-arm64.zip

Käynnistys

Tämän actionin voi käynnistää kahdella tavalla. Ensimmäinen on git tagin käyttäminen (tässä tapauksessa cli- -alkuinen tagi), joka on ns. tuotantotapa, koska GitHubin release vaatii aina tagin käyttämistä. Toinen on workflown manuaalinen suoritus projektin Actions-osiosta, jonka avulla on helpompi varmistaa, ettei koodissa ole mitään ongelmaa. Workflown manuaalinen käynnistys ei siis tee Releasea GitHubiin.

on:
  push:
    tags:
      - cli-*
  workflow_dispatch:

Käyttöjärjestelmämatriisi

Koska kääntäminen on tarkoitus tehdä sekä Windows-, Linux- että Mac-käyttöjärjestelmillä, otetaan avuksi strategia-matriisi, jossa on listattu kaikki halutut runnerit, joilla koodi on tarkoitus kääntää.

Windowsilla ja Linuxilla kohteena on x64-yhteensopiva suoritin ja Macin osalta kohteena on arm64. Jos tarkoitus olisi tukea esim. Linuxia ARM64:n osalta, pitäisi mukaan lisätä uusi runneri, sillä ubuntu-latest on vain x64-yhteensopiva.

runs-on: ${{ matrix.os }}
  strategy:
    matrix:
      os: [windows-latest, macos-latest, ubuntu-latest]

Alustakohtainen kääntäminen

Olen eriyttänyt kaikki alustakohtaiset kääntämiset omiksi koodiosioikseen, koska tietyissä tilanteissa jokin alusta saattaa kaivata omia parametrejaan, ja/tai jotain esi/jälkikäsittelyä.

if-ehdot pitävät tässä tapauksessa huolen, että haluttu koodi ajetaan vain tietyn runnerin kanssa.

.NET AOT vaatii aina publish-parametrin käyttämistä, ja varsinaisen kääntämisen jälkeen luon jokaisella alustalla oman artifaktin, joka talletetaan GitHubin väliaikaiseen arkistoon. Nämä artifaktit käsitellään seuraavassa vaiheessa

- name: Publish Windows x64
  run: dotnet publish -r win-x64 -c Release -o win-x64
  working-directory: cli
  if: matrix.os == 'windows-latest'
- uses: actions/upload-artifact@v6
  if: matrix.os == 'windows-latest'
  with:
    name: codec8cli-win-x64
    path: cli/win-x64
    compression-level: 9 # maximum compression

Jobsien riippuvuudet

Jotta jobsit ajetaan perättäin, pitää niille luoda riippuvuussuhde, joka tapahtuu needs-avainsanalla.

needs: buildaots

Artifaktien lataaminen

Toisena vaiheena toimiva releaseartifacts job ei käytä gitistä löytyviä koodeja, vaan se vain lataa ensimmäisessä osassa luodut artifaktit. Ilman parametrejä se lataa ja purkaa kaikki artifaktit omiin kansioihinsa (kansioiden nimeäminen noudattaa artifaktien nimiä).

- uses: actions/download-artifact@v8

Koodin paketointi (tässä tapauksessa zippaus)

Kun kaikki artifaktit on ladattu ja purettu omiin kansioihinsa, paketoidaan ne releasea varten omiksi .zip-tiedostoiksi. Tässä kohtaa voi luonnollisesti käyttää jotain muutakin työkalua, mutta zip löytyy Linux-runnerista valmiina, joten se on helppo ottaa käyttöön. Mukana oleva -9 parametri koettaa pakata tiedostot mahdollisimman tiiviisti.

- name: Zip win-x64
  run: zip -9 -r ../codec8cli-win-x64.zip .
  working-directory: codec8cli-win-x64
- name: Zip linux-x64
  run: zip -9 -r ../codec8cli-linux-x64.zip .
  working-directory: codec8cli-linux-x64
- name: Zip mac-arm64
  run: zip -9 -r ../codec8cli-mac-arm64.zip .
  working-directory: codec8cli-mac-arm64

Releasen tekeminen

Viimeinen vaihe on laittaa tehdyt .zip-tiedostot jakeluun projektin omaan Release-osioon. Yksinkertaisuuden vuoksi käytössä on softprops/action-gh-release-action, mutta halutessaan voi käyttää jotain vastaavaa actionia. if-ehto pitää huolen siitä, että manuaalisella käynnistyksellä ei koeteta tehdä releasea, koska tällöin tärkeä git tagi puuttuu.

On tärkää huomata, että oikeus Releasen tekemiseen täytyy antaa erikseen valitsemalla Read and write permissions projektin asetuksista (Settings) löytyvästä Actions -> General -osiosta.

- name: Release
  uses: softprops/action-gh-release@v2
  if: github.ref_type == 'tag'
  with:
    files: |
    codec8cli-win-x64.zip
    codec8cli-linux-x64.zip
    codec8cli-mac-arm64.zip

🔨