First push
ASP.NET AJAX / build_web_app (push) Waiting to run
Angular / build_angular (push) Waiting to run
ASP.NET Core (with Reporting) / build_windows (push) Waiting to run
Blazor (with Reporting) / build_windows (push) Waiting to run
Blazor (with Reporting) / build_linux (push) Waiting to run
Console (.NET) / build_console (arm64, linux) (push) Waiting to run
Console (.NET) / build_console (arm64, win) (push) Waiting to run
Console (.NET) / build_console (x64, linux) (push) Waiting to run
Console (.NET) / build_console (x64, win) (push) Waiting to run
MAUI / Windows Smoketest (push) Waiting to run
MAUI / Android Smoketest (push) Waiting to run
MAUI / iOS Smoketest (push) Waiting to run
MAUI / MacCatalyst Smoketest (push) Waiting to run
WinForms (.NET Framework) / build_desktop (Release, x64) (push) Waiting to run
WinForms (.NET Framework) / build_desktop (Release, x86) (push) Waiting to run
WinUI3 / build-windows (push) Waiting to run
WPF (.NET Framework) / build_desktop (Release, x64) (push) Waiting to run
WPF (.NET Framework) / build_desktop (Release, x86) (push) Waiting to run
ASP.NET Core (with Reporting) - Docker / Microsoft Base - Publish to Docker Hub (push) Waiting to run
ASP.NET Core (with Reporting) - Docker / CentOS Base - Publish to Docker Hub (push) Waiting to run
Blazor (with Reporting) - Docker / Dockerfile Build and Publish (push) Waiting to run
ASP.NET AJAX / build_web_app (push) Waiting to run
Angular / build_angular (push) Waiting to run
ASP.NET Core (with Reporting) / build_windows (push) Waiting to run
Blazor (with Reporting) / build_windows (push) Waiting to run
Blazor (with Reporting) / build_linux (push) Waiting to run
Console (.NET) / build_console (arm64, linux) (push) Waiting to run
Console (.NET) / build_console (arm64, win) (push) Waiting to run
Console (.NET) / build_console (x64, linux) (push) Waiting to run
Console (.NET) / build_console (x64, win) (push) Waiting to run
MAUI / Windows Smoketest (push) Waiting to run
MAUI / Android Smoketest (push) Waiting to run
MAUI / iOS Smoketest (push) Waiting to run
MAUI / MacCatalyst Smoketest (push) Waiting to run
WinForms (.NET Framework) / build_desktop (Release, x64) (push) Waiting to run
WinForms (.NET Framework) / build_desktop (Release, x86) (push) Waiting to run
WinUI3 / build-windows (push) Waiting to run
WPF (.NET Framework) / build_desktop (Release, x64) (push) Waiting to run
WPF (.NET Framework) / build_desktop (Release, x86) (push) Waiting to run
ASP.NET Core (with Reporting) - Docker / Microsoft Base - Publish to Docker Hub (push) Waiting to run
ASP.NET Core (with Reporting) - Docker / CentOS Base - Publish to Docker Hub (push) Waiting to run
Blazor (with Reporting) - Docker / Dockerfile Build and Publish (push) Waiting to run
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
# This example shows you how you can use the named environment variables in the nuget.config file to set the credentials, for more information see https://github.com/LanceMcCarthy/DevOpsExamples#github-actions-using-secrets-to-set-environment-variables
|
||||
name: ASP.NET AJAX
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- "ajax/*"
|
||||
paths:
|
||||
- 'src/Ajax/**/*'
|
||||
- '.github/workflows/main_build-ajax.yml'
|
||||
|
||||
env:
|
||||
CSPROJ_PATH: "src/Ajax/MySite.sln"
|
||||
NUGETCONFIG_PATH: "src/NuGet.Config"
|
||||
|
||||
jobs:
|
||||
build_web_app:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Nuget.exe
|
||||
uses: nuget/setup-nuget@v2
|
||||
with:
|
||||
nuget-version: '5.x'
|
||||
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
# Important: We are using nuget CLI (not dotnet CLI) See https://docs.microsoft.com/en-us/nuget/reference/nuget-exe-cli-reference
|
||||
- name: NuGet.exe Restore
|
||||
run: nuget restore ${{env.CSPROJ_PATH}} -ConfigFile ${{env.NUGETCONFIG_PATH}}
|
||||
env:
|
||||
TELERIK_USERNAME: "api-key" # Variable name used in the nuget.config file
|
||||
TELERIK_PASSWORD: ${{secrets.TELERIK_NUGET_KEY}} # Variable name used in the nuget.config file
|
||||
|
||||
- name: Build the AJAX application
|
||||
run: msbuild ${{env.CSPROJ_PATH}} /t:Restore /p:Configuration=Release /p:RuntimeIdentifier=any
|
||||
env:
|
||||
TELERIK_LICENSE: ${{secrets.TELERIK_LICENSE_KEY}}
|
||||
@@ -0,0 +1,37 @@
|
||||
name: Angular
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- "angular/*"
|
||||
paths:
|
||||
- 'src/Kendo/angular_demo/**/*'
|
||||
- '.github/workflows/main_build-angular.yml'
|
||||
|
||||
jobs:
|
||||
build_angular:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Build App
|
||||
working-directory: src/Kendo/angular_demo
|
||||
run: |
|
||||
# 1. Clean the angular cache, to avoid using any expired keys
|
||||
rm -rf .angular/cache
|
||||
|
||||
# 2. Install your project dependencies
|
||||
npm install
|
||||
# npm install --save @progress/kendo-licensing; # if missing from package.json
|
||||
|
||||
#3. Activate
|
||||
npx kendo-ui-license activate
|
||||
|
||||
#4. Build the project
|
||||
npm run build --prod
|
||||
env:
|
||||
TELERIK_LICENSE: ${{secrets.TELERIK_LICENSE_KEY}}
|
||||
@@ -0,0 +1,56 @@
|
||||
name: ASP.NET Core (with Reporting)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- "aspnetcore/*"
|
||||
paths:
|
||||
- 'src/AspNetCore/**/*'
|
||||
- '.github/workflows/main_build-aspnetcore.yml'
|
||||
|
||||
permissions:
|
||||
id-token: write # JWT for Akeyless and Azure auth
|
||||
|
||||
env:
|
||||
DOTNET_VERSION: "10.0.x"
|
||||
PROJECT_PATH: src/AspNetCore/MyAspNetCoreApp/MyAspNetCoreApp.csproj
|
||||
NUGETCONFIG_PATH: src/NuGet.Config
|
||||
|
||||
jobs:
|
||||
build_windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
# Using AKeyless for secrets in this demo, but you can use github Secrets instead
|
||||
- name: Fetch secrets from AKeyless
|
||||
id: akeyless
|
||||
uses: LanceMcCarthy/akeyless-action@v5
|
||||
with:
|
||||
access-id: 'p-4blpeo5zdfeaom'
|
||||
static-secrets: |
|
||||
{
|
||||
"/progress/TELERIK_NUGET_KEY":"TELERIK_NUGET_KEY",
|
||||
"/progress/TELERIK_LICENSE":"TELERIK_LICENSE_KEY"
|
||||
}
|
||||
export-secrets-to-outputs: true
|
||||
export-secrets-to-environment: false
|
||||
|
||||
- name: Setup .NET Core SDK
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
dotnet-version: ${{env.DOTNET_VERSION}}
|
||||
|
||||
- name: Restore NuGet Packages
|
||||
run: dotnet restore ${{env.PROJECT_PATH}} --configfile ${{env.NUGETCONFIG_PATH}}
|
||||
env:
|
||||
TELERIK_USERNAME: "api-key"
|
||||
TELERIK_PASSWORD: ${{steps.akeyless.outputs.TELERIK_NUGET_KEY}}
|
||||
|
||||
- name: Build ASP.NET Core Project
|
||||
run: dotnet build ${{env.PROJECT_PATH}} -c Debug --no-restore
|
||||
env:
|
||||
TELERIK_LICENSE: ${{steps.akeyless.outputs.TELERIK_LICENSE_KEY}}
|
||||
@@ -0,0 +1,65 @@
|
||||
name: ASP.NET Core (with Reporting) - Azure
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
DOTNET_VERSION: "10.0.x"
|
||||
PROJECT_PATH: src/AspNetCore/MyAspNetCoreApp/MyAspNetCoreApp.csproj
|
||||
NUGETCONFIG_PATH: src/NuGet.Config
|
||||
AZURE_WEBAPP_NAME: DevOpsExamplesCore
|
||||
ARTIFACTS_DIRECTORY: "src/AspNetCore/MyAspNetCoreApp/artifacts"
|
||||
TELERIK_USERNAME: "api-key"
|
||||
TELERIK_PASSWORD: ${{secrets.TELERIK_NUGET_KEY}}
|
||||
TELERIK_LICENSE: ${{secrets.TELERIK_LICENSE_KEY}}
|
||||
|
||||
jobs:
|
||||
build_windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
# ----------------------------------------------------------------------- #
|
||||
# BUILD
|
||||
# ----------------------------------------------------------------------- #
|
||||
|
||||
- name: Setup .NET Core SDK
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
dotnet-version: ${{env.DOTNET_VERSION}}
|
||||
|
||||
- name: Restore NuGet Packages
|
||||
run: dotnet restore ${{env.PROJECT_PATH}} --configfile ${{env.NUGETCONFIG_PATH}}
|
||||
|
||||
- name: Build ASP.NET Core Project
|
||||
run: dotnet publish ${{env.PROJECT_PATH}} -o ${{env.ARTIFACTS_DIRECTORY}} --no-restore
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------- #
|
||||
# DEPLOY to https://devopsexamplescore.azurewebsites.net/
|
||||
# ----------------------------------------------------------------------- #
|
||||
|
||||
# Option 1
|
||||
# Deploy using the publish profile saved as a Github Actions secret
|
||||
- name: Deploy to Azure WebApp
|
||||
uses: azure/webapps-deploy@v3
|
||||
with:
|
||||
app-name: ${{env.AZURE_WEBAPP_NAME}}
|
||||
publish-profile: ${{secrets.DEVOPSEXAMPLESCORE_PUBLISHSETTINGS}}
|
||||
package: ${{env.ARTIFACTS_DIRECTORY}}
|
||||
|
||||
# Option 2
|
||||
# Use a service principal to log into Azure, no reliance on GitHub secrets
|
||||
# - name: Azure Login
|
||||
# uses: azure/login@v2
|
||||
# with:
|
||||
# client-id: ${{secrets.AZUREAPPSERVICE_CLIENTID}}
|
||||
# tenant-id: ${{secrets.AZUREAPPSERVICE_TENANTID}}
|
||||
# subscription-id: ${{secrets.AZUREAPPSERVICE_SUBSCRIPTIONID}}
|
||||
|
||||
# - name: Deploy to Azure WebApp
|
||||
# uses: azure/webapps-deploy@v3
|
||||
# with:
|
||||
# app-name: ${{env.AZURE_WEBAPP_NAME}}
|
||||
# package: ${{env.ARTIFACTS_DIRECTORY}}
|
||||
@@ -0,0 +1,108 @@
|
||||
# This workflow has three examples (one for IIS, two using containers)
|
||||
# [Option A] Typical IIS build & publish
|
||||
# [Option B] DOCKER FILE BUILD - publishes the image to ghcr.io (GitHub container registry)
|
||||
# [Option C] .NET SDK CONTAINER BUILD - publishes the image to Docker Hub
|
||||
name: Blazor (with Reporting)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- "blazor/*"
|
||||
paths:
|
||||
- 'src/Blazor/**/*'
|
||||
- '.github/workflows/main_build-blazor.yml'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write # to publish to GitHub container registry
|
||||
id-token: write # # JWT for Akeyless auth
|
||||
|
||||
env:
|
||||
CONFIGURATION: Release
|
||||
BLAZOR_PROJ_PATH: src/Blazor/MyBlazorApp/MyBlazorApp.csproj
|
||||
TEST_PROJ_PATH: src/Blazor/MyBlazorApp.Tests/MyBlazorApp.Tests.csproj
|
||||
NUGET_CONFIG_PATH: src/NuGet.Config
|
||||
DOTNET_VERSION: "10.0.x"
|
||||
|
||||
jobs:
|
||||
build_windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# Using AKeyless for secrets in this demo
|
||||
- name: Fetch secrets from AKeyless
|
||||
id: akeyless
|
||||
uses: LanceMcCarthy/akeyless-action@v5
|
||||
with:
|
||||
access-id: 'p-4blpeo5zdfeaom'
|
||||
static-secrets: |
|
||||
{
|
||||
"/progress/TELERIK_NUGET_KEY":"TELERIK_NUGET_KEY",
|
||||
"/progress/TELERIK_LICENSE":"TELERIK_LICENSE_KEY"
|
||||
}
|
||||
export-secrets-to-outputs: true
|
||||
export-secrets-to-environment: false
|
||||
|
||||
- name: Setup .NET Core SDK
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: ${{env.DOTNET_VERSION}}
|
||||
|
||||
- name: Restore NuGet Packages
|
||||
run: |
|
||||
dotnet restore ${{env.BLAZOR_PROJ_PATH}} --configfile ${{env.NUGET_CONFIG_PATH}}
|
||||
dotnet restore ${{env.TEST_PROJ_PATH}} --configfile ${{env.NUGET_CONFIG_PATH}}
|
||||
env:
|
||||
TELERIK_USERNAME: "api-key"
|
||||
TELERIK_PASSWORD: ${{steps.akeyless.outputs.TELERIK_NUGET_KEY}}
|
||||
|
||||
- name: Build Test Project
|
||||
run: dotnet build ${{env.TEST_PROJ_PATH}} -c ${{env.CONFIGURATION}} --no-restore
|
||||
env:
|
||||
TELERIK_LICENSE: ${{steps.akeyless.outputs.TELERIK_LICENSE_KEY}}
|
||||
|
||||
build_linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# Using AKeyless for secrets in this demo
|
||||
- name: Fetch secrets from AKeyless
|
||||
id: akeyless
|
||||
uses: LanceMcCarthy/akeyless-action@v5
|
||||
with:
|
||||
access-id: 'p-4blpeo5zdfeaom'
|
||||
static-secrets: |
|
||||
{
|
||||
"/progress/TELERIK_NUGET_KEY":"TELERIK_NUGET_KEY",
|
||||
"/progress/TELERIK_LICENSE":"TELERIK_LICENSE_KEY"
|
||||
}
|
||||
export-secrets-to-outputs: true
|
||||
export-secrets-to-environment: false
|
||||
|
||||
- name: Setup .NET Core SDK
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: ${{env.DOTNET_VERSION}}
|
||||
|
||||
- name: Restore NuGet Packages
|
||||
run: |
|
||||
dotnet restore ${{env.BLAZOR_PROJ_PATH}} --configfile ${{env.NUGET_CONFIG_PATH}}
|
||||
dotnet restore ${{env.TEST_PROJ_PATH}} --configfile ${{env.NUGET_CONFIG_PATH}}
|
||||
env:
|
||||
TELERIK_USERNAME: "api-key"
|
||||
TELERIK_PASSWORD: ${{steps.akeyless.outputs.TELERIK_NUGET_KEY}}
|
||||
|
||||
- name: Build Test Project
|
||||
run: dotnet build ${{env.TEST_PROJ_PATH}} -c ${{env.CONFIGURATION}} --no-restore
|
||||
env:
|
||||
TELERIK_LICENSE: ${{steps.akeyless.outputs.TELERIK_LICENSE_KEY}}
|
||||
@@ -0,0 +1,50 @@
|
||||
# This example shows you how ot use Akeyless to fetch the required secrets instead of GitHub Actions secrets
|
||||
name: Console (.NET)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- "console/*"
|
||||
paths:
|
||||
- 'src/Console/**/*'
|
||||
- '.github/workflows/main_build-console.yml'
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: pwsh
|
||||
|
||||
env:
|
||||
CSPROJ_PATH: src/Console/MyDocProcApp/MyDocProcApp.csproj
|
||||
NUGETCONFIG_PATH: src/NuGet.Config
|
||||
BUILD_CONFIGURATION: Release
|
||||
|
||||
jobs:
|
||||
build_console:
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
matrix:
|
||||
os: [linux, win]
|
||||
config: [x64, arm64]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '10.0.x'
|
||||
|
||||
- name: Update NuGet Package Sources
|
||||
run: dotnet nuget update source 'Telerik_v3_Feed' -s 'https://nuget.telerik.com/v3/index.json' -u "api-key" -p ${{secrets.TELERIK_NUGET_KEY}} --configfile ${{env.NUGETCONFIG_PATH}} --store-password-in-clear-text
|
||||
|
||||
- name: Restore NuGet packages
|
||||
run: dotnet restore ${{env.CSPROJ_PATH}} --configfile ${{env.NUGETCONFIG_PATH}} --runtime ${{matrix.os}}-${{matrix.config}}
|
||||
|
||||
- name: Build project
|
||||
run: dotnet build ${{env.CSPROJ_PATH}} --configuration ${{env.BUILD_CONFIGURATION}} --runtime ${{matrix.os}}-${{matrix.config}} --no-self-contained --no-restore
|
||||
env:
|
||||
TELERIK_LICENSE: ${{secrets.TELERIK_LICENSE_KEY}}
|
||||
@@ -0,0 +1,119 @@
|
||||
name: Console (.NET) - Trusted Signing
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: pwsh
|
||||
|
||||
permissions:
|
||||
id-token: write # For OIDC auth
|
||||
|
||||
env:
|
||||
CSPROJ_PATH: src/Console/MyDocProcApp/MyDocProcApp.csproj
|
||||
NUGETCONFIG_PATH: src/NuGet.Config
|
||||
BUILD_CONFIGURATION: Release
|
||||
|
||||
jobs:
|
||||
build_console:
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
matrix:
|
||||
os: [linux, win]
|
||||
config: [x64, arm64]
|
||||
env:
|
||||
OUTPUT_DIR: ${{github.workspace}}/output/${{matrix.os}}-${{matrix.config}}/
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '10.0.x'
|
||||
|
||||
- name: Update NuGet Package Sources
|
||||
run: dotnet nuget update source 'Telerik_v3_Feed' -s 'https://nuget.telerik.com/v3/index.json' -u "api-key" -p ${{secrets.TELERIK_NUGET_KEY}} --configfile ${{env.NUGETCONFIG_PATH}} --store-password-in-clear-text
|
||||
|
||||
- name: Restore NuGet packages
|
||||
run: dotnet restore ${{env.CSPROJ_PATH}} --configfile ${{env.NUGETCONFIG_PATH}} --runtime ${{matrix.os}}-${{matrix.config}}
|
||||
|
||||
- name: Build project
|
||||
run: dotnet publish ${{env.CSPROJ_PATH}} --configuration ${{env.BUILD_CONFIGURATION}} --runtime ${{matrix.os}}-${{matrix.config}} --no-self-contained --no-restore --output ${{env.OUTPUT_DIR}}
|
||||
env:
|
||||
TELERIK_LICENSE: ${{secrets.TELERIK_LICENSE_KEY}}
|
||||
|
||||
- name: Attach artifacts
|
||||
id: upload-artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "Console_${{matrix.os}}-${{matrix.config}}"
|
||||
path: ${{env.OUTPUT_DIR}}
|
||||
if-no-files-found: error
|
||||
retention-days: 30
|
||||
|
||||
codesign_release:
|
||||
name: Codesign Release
|
||||
if: ${{ success() }}
|
||||
runs-on: windows-latest
|
||||
needs: [build_console]
|
||||
steps:
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: ${{github.workspace}}/artifacts/
|
||||
|
||||
# No secrets needed, uses the GitHub OIDC token to authenticate.
|
||||
- name: Azure login using OIDC via GitHub
|
||||
uses: azure/login@v2
|
||||
id: azlogin
|
||||
with:
|
||||
client-id: "32daa13b-f4bb-4809-8ef6-58cb39051acd"
|
||||
tenant-id: "bd47e796-3473-4b8a-9101-1f4c0c7af31a"
|
||||
subscription-id: "48ab4839-62af-4ab3-afe6-043ea4d7c137"
|
||||
|
||||
# Codesign files with Azure Trusted Signing
|
||||
- name: Sign files with Trusted Signing
|
||||
uses: azure/trusted-signing-action@v0.4.0
|
||||
with:
|
||||
endpoint: https://eus.codesigning.azure.net/
|
||||
trusted-signing-account-name: PrimaryCodeSign
|
||||
certificate-profile-name: lancemccarthylivepublic
|
||||
timestamp-rfc3161: http://timestamp.acs.microsoft.com
|
||||
timestamp-digest: SHA256
|
||||
file-digest: SHA256
|
||||
files-folder: ${{github.workspace}}/artifacts/
|
||||
files-folder-filter: exe
|
||||
files-folder-depth: 3
|
||||
exclude-azure-cli-credential: false
|
||||
exclude-environment-credential: true
|
||||
exclude-workload-identity-credential: true
|
||||
exclude-managed-identity-credential: true
|
||||
exclude-shared-token-cache-credential: true
|
||||
exclude-visual-studio-credential: true
|
||||
exclude-visual-studio-code-credential: true
|
||||
exclude-azure-powershell-credential: true
|
||||
exclude-azure-developer-cli-credential: true
|
||||
exclude-interactive-browser-credential: true
|
||||
|
||||
- name: Attach signed artifact
|
||||
id: upload-artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "Console_Codesigned"
|
||||
path: ${{github.workspace}}/artifacts/
|
||||
if-no-files-found: error
|
||||
retention-days: 30
|
||||
|
||||
- name: Delete unsigned artifacts from run
|
||||
uses: geekyeggo/delete-artifact@v5
|
||||
with:
|
||||
name: |
|
||||
Console_linux-x64
|
||||
Console_linux-arm64
|
||||
Console_win-x64
|
||||
Console_win-arm64
|
||||
failOnError: false
|
||||
@@ -0,0 +1,50 @@
|
||||
name: Console (.NET) - Artifactory Only
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: pwsh
|
||||
|
||||
jobs:
|
||||
build_console:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '10.0.x'
|
||||
|
||||
- name: Build Console App w/only Artifactory Source
|
||||
run: |
|
||||
# 1. Remove all existing package sources
|
||||
$sourceList = dotnet nuget list source
|
||||
$sourceNames = @()
|
||||
foreach ($line in $sourceList) {
|
||||
if ($line -match '^\s*\d+\.\s+(.*)\s+\[Enabled\]') {
|
||||
$sourceNames += $matches[1].Trim()
|
||||
}
|
||||
}
|
||||
foreach ($name in $sourceNames) {
|
||||
dotnet nuget remove source "$name"
|
||||
Write-Host "Removed $name ..."
|
||||
}
|
||||
|
||||
# 2. Add Artifactory source with credentials from GitHub Secrets
|
||||
dotnet nuget add source "https://bed-artifactory.bedford.progress.com/artifactory/api/nuget/v3/dt-nuget-virtual-tierpoint/index.json" `
|
||||
--name "artifactory_virtual" `
|
||||
--username ${{secrets.ARTIFACTORY_NUGET_USERNAME}} `
|
||||
--password ${{secrets.ARTIFACTORY_NUGET_PASSWORD}} `
|
||||
--store-password-in-clear-text
|
||||
|
||||
# 3. List sources to verify
|
||||
dotnet nuget list source
|
||||
|
||||
# 4. Build the project
|
||||
dotnet build "src/Console/MyDocProcApp/MyDocProcApp.csproj"
|
||||
env:
|
||||
TELERIK_LICENSE: ${{secrets.TELERIK_LICENSE_KEY}}
|
||||
@@ -0,0 +1,137 @@
|
||||
name: MAUI
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'src/MAUI/**/*'
|
||||
- '.github/workflows/main_build-maui.yml'
|
||||
|
||||
env:
|
||||
TELERIK_LICENSE: ${{secrets.TELERIK_LICENSE_KEY}}
|
||||
PROJECT_PATH: "src/MAUI/MauiDemo.csproj"
|
||||
NUGETCONFIG_PATH: "src/NuGet.Config"
|
||||
DOTNET_VERSION: "10.0.x"
|
||||
MAC_DOTNET_VERSION: "10.0.203" # Used to avoid Xcode and MAUI workload problems
|
||||
TFM_VERSION: "net10.0"
|
||||
XCODE_VERSION: '26.4'
|
||||
BUILD_CONFIG: "Debug"
|
||||
|
||||
jobs:
|
||||
maui-windows:
|
||||
name: Windows Smoketest
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
dotnet-version: ${{env.DOTNET_VERSION}}
|
||||
|
||||
# Only needed for WinUI builds
|
||||
- name: Add msbuild to PATH
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
|
||||
- name: Install MAUI workloads
|
||||
run: dotnet workload install maui --source https://api.nuget.org/v3/index.json
|
||||
|
||||
- name: Set Telerik NuGet Credentials
|
||||
run: dotnet nuget update source 'Telerik_v3_Feed' -s 'https://nuget.telerik.com/v3/index.json' -u 'api-key' -p "${{secrets.TELERIK_NUGET_KEY}}" --configfile ${{env.NUGETCONFIG_PATH}} --store-password-in-clear-text
|
||||
|
||||
- name: Restore NuGet packages
|
||||
run: dotnet restore ${{env.PROJECT_PATH}} --configfile ${{env.NUGETCONFIG_PATH}}
|
||||
|
||||
- name: Build Maui WinUI project
|
||||
run: dotnet build ${{env.PROJECT_PATH}} -c ${{env.BUILD_CONFIG}} -f "${{env.TFM_VERSION}}-windows10.0.22621.0" --no-restore
|
||||
|
||||
|
||||
maui-android:
|
||||
name: Android Smoketest
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
dotnet-version: ${{env.DOTNET_VERSION}}
|
||||
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'microsoft'
|
||||
java-version: '11'
|
||||
|
||||
- name: Install MAUI workloads
|
||||
run: dotnet workload install maui --source https://api.nuget.org/v3/index.json
|
||||
|
||||
- name: Set Telerik NuGet Credentials
|
||||
run: dotnet nuget update source 'Telerik_v3_Feed' -s 'https://nuget.telerik.com/v3/index.json' -u 'api-key' -p "${{secrets.TELERIK_NUGET_KEY}}" --configfile ${{env.NUGETCONFIG_PATH}} --store-password-in-clear-text
|
||||
|
||||
- name: Restore NuGet packages
|
||||
run: dotnet restore ${{env.PROJECT_PATH}} --configfile ${{env.NUGETCONFIG_PATH}}
|
||||
|
||||
- name: Build Maui Android project
|
||||
run: dotnet build ${{env.PROJECT_PATH}} -c ${{env.BUILD_CONFIG}} -f "${{env.TFM_VERSION}}-android" --no-restore
|
||||
|
||||
|
||||
maui-ios:
|
||||
name: iOS Smoketest
|
||||
runs-on: macos-26
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- uses: maxim-lobanov/setup-xcode@v1
|
||||
with:
|
||||
xcode-version: ${{env.XCODE_VERSION}}
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
dotnet-version: ${{env.MAC_DOTNET_VERSION}}
|
||||
|
||||
- name: Install MAUI workloads
|
||||
run: dotnet workload install maui --source https://api.nuget.org/v3/index.json
|
||||
|
||||
- name: Set Telerik NuGet Credentials
|
||||
run: dotnet nuget update source 'Telerik_v3_Feed' -s 'https://nuget.telerik.com/v3/index.json' -u 'api-key' -p "${{secrets.TELERIK_NUGET_KEY}}" --configfile ${{env.NUGETCONFIG_PATH}} --store-password-in-clear-text
|
||||
|
||||
- name: Restore NuGet packages
|
||||
run: dotnet restore ${{env.PROJECT_PATH}} --configfile ${{env.NUGETCONFIG_PATH}}
|
||||
|
||||
- name: Build MAUI iOS project
|
||||
run: dotnet build ${{env.PROJECT_PATH}} -c ${{env.BUILD_CONFIG}} -f "${{env.TFM_VERSION}}-ios" --no-restore -p:PublishTrimmed=True -p:MtouchLink=SdkOnly
|
||||
|
||||
|
||||
maui-macos:
|
||||
name: MacCatalyst Smoketest
|
||||
runs-on: macos-26
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- uses: maxim-lobanov/setup-xcode@v1
|
||||
with:
|
||||
xcode-version: ${{env.XCODE_VERSION}}
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
dotnet-version: ${{env.MAC_DOTNET_VERSION}}
|
||||
|
||||
- name: Install MAUI workloads
|
||||
run: dotnet workload install maui --source https://api.nuget.org/v3/index.json
|
||||
|
||||
- name: Set Telerik NuGet Credentials
|
||||
run: dotnet nuget update source 'Telerik_v3_Feed' -s 'https://nuget.telerik.com/v3/index.json' -u 'api-key' -p "${{secrets.TELERIK_NUGET_KEY}}" --configfile ${{env.NUGETCONFIG_PATH}} --store-password-in-clear-text
|
||||
|
||||
- name: Restore NuGet packages
|
||||
run: dotnet restore ${{env.PROJECT_PATH}} --configfile ${{env.NUGETCONFIG_PATH}}
|
||||
|
||||
- name: Build MAUI MacCatalyst project
|
||||
run: dotnet build ${{env.PROJECT_PATH}} -c ${{env.BUILD_CONFIG}} -f "${{env.TFM_VERSION}}-maccatalyst" --no-restore -p:PublishTrimmed=True -p:MtouchLink=SdkOnly
|
||||
@@ -0,0 +1,771 @@
|
||||
name: MAUI (Distribution)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: pwsh
|
||||
|
||||
permissions:
|
||||
actions: write # Needed to delete artifacts after bundle upload
|
||||
contents: write # Needed to create GitHub Releases
|
||||
id-token: write # Needed for Azure auth (OIDC)
|
||||
|
||||
env:
|
||||
# ____Global____________________________________________
|
||||
APP_NAME: "MauiDemo"
|
||||
PROJECT_PATH: "src/MAUI/MauiDemo.csproj"
|
||||
PROJECT_DIRECTORY: "src/MAUI"
|
||||
SDK_VERSION: '10.0.x'
|
||||
NET_TFM: 'net10.0'
|
||||
XCODE_VERSION: '26.4'
|
||||
MAC_DOTNET_VERSION: '10.0.203'
|
||||
NUGET_CONFIG_PATH: 'src/nuget.config'
|
||||
TELERIK_NUGET_KEY: ${{secrets.TELERIK_NUGET_KEY}}
|
||||
TELERIK_LICENSE: ${{secrets.TELERIK_LICENSE_KEY}}
|
||||
# ____Android___________________________________________
|
||||
ANDROID_ARTIFACTS_PATH: "artifacts_android"
|
||||
ANDROID_KEYSTORE_PATH: "${{github.workspace}}/android-upload.keystore"
|
||||
JAVA_VERSION: '17'
|
||||
JAVA_DISTRIBUTION: 'microsoft'
|
||||
# ____MacCatalyst_______________________________________
|
||||
APPLE_DEV_ID_APP_CERT_NAME: "Developer ID Application: Lancelot Software, LLC (L65255N3F7)"
|
||||
APPLE_DEV_ID_INSTALLER_CERT_NAME: "Developer ID Installer: Lancelot Software, LLC (L65255N3F7)"
|
||||
APPLE_NOTARY_TEAM_ID: "L65255N3F7"
|
||||
MAC_PACKAGE_NAME: "MauiDemo-MacCatalyst"
|
||||
MAC_APP_BUNDLE_PATH: "src/Maui/bin/Release/net10.0-maccatalyst/MauiDemo.app"
|
||||
MAC_ARTIFACTS_PATH: "artifacts/maccatalyst"
|
||||
# ____iOS______________________________________________ (also check matrix vars)
|
||||
APPLE_APP_ID: "com.lancelotsoftware.MauiDemoApp"
|
||||
IOS_RID: ios-arm64
|
||||
# ____Windows__________________________________________ (also check matrix vars)
|
||||
WINDOWS_ARTIFACTS_PATH: "artifacts_windows"
|
||||
SERVICE_PRINCIPAL_CLIENT_ID: "32daa13b-f4bb-4809-8ef6-58cb39051acd"
|
||||
SERVICE_PRINCIPAL_TENANT_ID: "bd47e796-3473-4b8a-9101-1f4c0c7af31a"
|
||||
SERVICE_PRINCIPAL_SUBSCRIPTION_ID: "48ab4839-62af-4ab3-afe6-043ea4d7c137"
|
||||
SIGNING_ACCT_NAME: "PrimaryCodeSign"
|
||||
SIGNING_ACCT_CERT_PROFILE: "lancemccarthylivepublic"
|
||||
SIGNING_ACCT_ENDPOINT_URL: "https://eus.codesigning.azure.net/"
|
||||
|
||||
# ------------------ REQUIRED SECRETS ---------------- #
|
||||
# ____Global____________________________________________
|
||||
# TELERIK_NUGET_KEY
|
||||
# TELERIK_LICENSE_KEY
|
||||
# ____Android___________________________________________
|
||||
# ANDROID_SIGNING_KEYSTORE_BASE64
|
||||
# ANDROID_SIGNING_KEYSTORE_PASS
|
||||
# ANDROID_SIGNING_KEY_ALIAS
|
||||
# ANDROID_SIGNING_KEY_PASS
|
||||
# ____MacCatalyst_______________________________________
|
||||
# APPLE_DEVELOPER_ID_INSTALLER_CERT_BASE64
|
||||
# APPLE_DEVELOPER_ID_INSTALLER_CERT_PASSWORD
|
||||
# APPLE_DEVELOPER_ID_APPLICATION_CERT_BASE64
|
||||
# APPLE_NOTARY_APPLE_ID
|
||||
# APPLE_NOTARY_APP_PASSWORD
|
||||
# ____iOS______________________________________________
|
||||
# APPLE_DISTRIBUTION_CERT_BASE64
|
||||
# APPLE_DISTRIBUTION_CERT_PASSWORD
|
||||
# APPSTORE_API_ISSUER_ID
|
||||
# APPSTORE_API_KEY_ID
|
||||
# APPSTORE_API_PRIVATE_KEY
|
||||
# ____Windows__________________________________________
|
||||
# No additional secrets needed, uses Azure Trusted Signing.
|
||||
|
||||
|
||||
jobs:
|
||||
# ********************************************************************************** #
|
||||
# Shared Resources #
|
||||
# ********************************************************************************** #
|
||||
shared-resources:
|
||||
name: Create Shared Resources
|
||||
runs-on: windows-latest
|
||||
outputs:
|
||||
app_version: ${{steps.version-creator.outputs.app_version}}
|
||||
steps:
|
||||
# Generates a version number using year.monthday.run_number (e.g., 2024.824.1)
|
||||
- name: Generate version number using date and run number
|
||||
id: version-creator
|
||||
shell: pwsh
|
||||
run: |
|
||||
$buildDay = Get-Date -Format "yyyy.Mdd"
|
||||
$runNumber = "$env:GITHUB_RUN_NUMBER"
|
||||
$ver = $buildDay + "." + $runNumber
|
||||
echo "app_version=$ver" >> $env:GITHUB_OUTPUT
|
||||
|
||||
|
||||
# ********************************************************************************** #
|
||||
# Android #
|
||||
# ********************************************************************************** #
|
||||
android:
|
||||
name: Build Android (Store Upload)
|
||||
runs-on: windows-latest
|
||||
needs: shared-resources
|
||||
if: ${{ success() && needs.shared-resources.outputs.app_version != '' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Decode the Keystore
|
||||
shell: pwsh
|
||||
run: |
|
||||
$file_bytes = [System.Convert]::FromBase64String("${{secrets.ANDROID_SIGNING_KEYSTORE_BASE64}}")
|
||||
[IO.File]::WriteAllBytes("${{env.ANDROID_KEYSTORE_PATH}}", $file_bytes)
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
dotnet-version: ${{env.SDK_VERSION}}
|
||||
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: ${{env.JAVA_DISTRIBUTION}}
|
||||
java-version: ${{env.JAVA_VERSION}}
|
||||
|
||||
- name: Install MAUI Workloads
|
||||
run: dotnet workload install maui --source https://api.nuget.org/v3/index.json
|
||||
|
||||
- name: Set Telerik NuGet Credentials
|
||||
run: dotnet nuget update source 'Telerik_v3_Feed' -s 'https://nuget.telerik.com/v3/index.json' -u 'api-key' -p "${{secrets.TELERIK_NUGET_KEY}}" --configfile '${{env.NUGET_CONFIG_PATH}}' --store-password-in-clear-text
|
||||
|
||||
- name: Restore NuGet packages
|
||||
run: dotnet restore ${{env.PROJECT_PATH}} --configfile ${{env.NUGET_CONFIG_PATH}}
|
||||
|
||||
- name: Publish MAUI Android
|
||||
run: |
|
||||
dotnet publish ${{env.PROJECT_PATH}} -c Release -f ${{env.NET_TFM}}-android /p:AndroidKeyStore=true /p:AndroidSigningKeyStore=${{env.ANDROID_KEYSTORE_PATH}} /p:AndroidSigningStorePass=${{secrets.ANDROID_SIGNING_KEYSTORE_PASS}} /p:AndroidSigningKeyAlias=${{secrets.ANDROID_SIGNING_KEY_ALIAS}} /p:AndroidSigningKeyPass=${{secrets.ANDROID_SIGNING_KEY_PASS}}
|
||||
|
||||
- name: Create artifacts folder
|
||||
run: |
|
||||
New-Item -ItemType Directory -Force -Path ${{env.ANDROID_ARTIFACTS_PATH}} | Out-Null
|
||||
|
||||
- name: Copy signed APKs & AABs
|
||||
run: |
|
||||
$publishRoot = "src/Maui/bin/Release/${{env.NET_TFM}}-android"
|
||||
$apkFiles = Get-ChildItem -Path $publishRoot -Filter *-Signed.apk -File -Recurse -ErrorAction SilentlyContinue
|
||||
$aabFiles = Get-ChildItem -Path $publishRoot -Filter *-Signed.aab -File -Recurse -ErrorAction SilentlyContinue
|
||||
|
||||
if ($apkFiles.Count -eq 0 -and $aabFiles.Count -eq 0) {
|
||||
throw "No signed Android APK/AAB files found under $publishRoot"
|
||||
}
|
||||
|
||||
$apkFiles | ForEach-Object { Copy-Item -Path $_.FullName -Destination ${{env.ANDROID_ARTIFACTS_PATH}} -Force }
|
||||
$aabFiles | ForEach-Object { Copy-Item -Path $_.FullName -Destination ${{env.ANDROID_ARTIFACTS_PATH}} -Force }
|
||||
|
||||
- name: Publish Android build artifacts
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: "${{env.APP_NAME}}_v${{needs.shared-resources.outputs.app_version}}_signed-android"
|
||||
path: "${{env.ANDROID_ARTIFACTS_PATH}}/*"
|
||||
if-no-files-found: error
|
||||
retention-days: 60
|
||||
|
||||
|
||||
# ********************************************************************************** #
|
||||
# Windows (Sideload - msixbundle) #
|
||||
# ********************************************************************************** #
|
||||
windows-sideload-packages:
|
||||
name: Build Windows (Sideload)
|
||||
needs: shared-resources
|
||||
runs-on: windows-latest
|
||||
if: ${{ needs.shared-resources.outputs.app_version != ''}}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- arch: x64
|
||||
runtime_id: win-x64
|
||||
platform: x64
|
||||
- arch: arm64
|
||||
runtime_id: win-arm64
|
||||
platform: ARM64
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup .NET Core SDK
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
dotnet-version: ${{env.SDK_VERSION}}
|
||||
|
||||
# Needed only for WinUI builds
|
||||
- name: Add msbuild to PATH
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
|
||||
- name: Install MAUI workloads
|
||||
run: dotnet workload install maui --source https://api.nuget.org/v3/index.json
|
||||
|
||||
- name: Set Telerik NuGet Credentials
|
||||
run: dotnet nuget update source 'Telerik_v3_Feed' -s 'https://nuget.telerik.com/v3/index.json' -u 'api-key' -p "${{secrets.TELERIK_NUGET_KEY}}" --configfile '${{env.NUGET_CONFIG_PATH}}' --store-password-in-clear-text
|
||||
|
||||
- name: Restore NuGet packages
|
||||
run: dotnet restore ${{env.PROJECT_PATH}} --configfile ${{env.NUGET_CONFIG_PATH}}
|
||||
|
||||
- name: Update manifest for sideload build
|
||||
run: |
|
||||
[xml]$manifest = Get-Content '${{env.PROJECT_DIRECTORY}}\Platforms\Windows\Package.appxmanifest'
|
||||
$manifest.Package.Identity.Version = "${{needs.shared-resources.outputs.app_version}}.0"
|
||||
$manifest.Save('${{env.PROJECT_DIRECTORY}}\Platforms\Windows\Package.appxmanifest')
|
||||
|
||||
- name: Publish ${{matrix.arch}} Windows package
|
||||
id: publish-package
|
||||
run: |
|
||||
$appVersion = "${{needs.shared-resources.outputs.app_version}}.0"
|
||||
$artifactDir = "${{github.workspace}}\${{env.WINDOWS_ARTIFACTS_PATH}}\${{matrix.arch}}"
|
||||
New-Item -ItemType Directory -Force -Path $artifactDir | Out-Null
|
||||
Write-Host "Publishing Windows ${{matrix.arch}}..."
|
||||
$publishArgs = @(
|
||||
'publish'
|
||||
'${{env.PROJECT_PATH}}'
|
||||
'-c', 'Release'
|
||||
'-f', '${{env.NET_TFM}}-windows10.0.19041.0'
|
||||
'-p:Platform=${{matrix.platform}}'
|
||||
'-p:AppxPackageBuildPlatform=${{matrix.platform}}'
|
||||
'-p:RuntimeIdentifierOverride=${{matrix.runtime_id}}'
|
||||
'-p:GenerateAppxPackageOnBuild=true'
|
||||
'-p:AppxPackageSigningEnabled=false'
|
||||
'-p:UapAppxPackageBuildMode=SideloadOnly'
|
||||
'-p:AppxBundle=Never'
|
||||
'-p:WindowsPackageType=MSIX'
|
||||
)
|
||||
& dotnet @publishArgs
|
||||
if ($LASTEXITCODE -ne 0) { throw "dotnet publish failed for ${{matrix.arch}} with exit code $LASTEXITCODE" }
|
||||
# MAUI writes MSIX to src\${{env.APP_NAME}}\AppPackages\<name>_<ver>_<arch>_Test\*.msix
|
||||
$appPackagesRoot = "src\${{env.APP_NAME}}\AppPackages"
|
||||
$candidates = Get-ChildItem -Path $appPackagesRoot -Filter *.msix -Recurse -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.FullName -notmatch '\\Dependencies\\' -and $_.Name -match "_${{matrix.arch}}\.msix$" }
|
||||
Write-Host "Found $($candidates.Count) candidate MSIX file(s) for ${{matrix.arch}}:"
|
||||
$candidates | ForEach-Object { Write-Host " $($_.FullName)" }
|
||||
$msix = $candidates | Sort-Object LastWriteTime -Descending | Select-Object -ExpandProperty FullName -First 1
|
||||
if (-not $msix) { throw "No .msix found after publish for ${{matrix.arch}}" }
|
||||
Write-Host "Found ${{matrix.arch}} package: $msix"
|
||||
Copy-Item -Path $msix -Destination "$artifactDir\${{env.APP_NAME}}.${{matrix.arch}}.msix" -Force
|
||||
echo "PACKAGE_PATH=$artifactDir\${{env.APP_NAME}}.${{matrix.arch}}.msix" >> $env:GITHUB_OUTPUT
|
||||
|
||||
- name: Upload ${{matrix.arch}} artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: "${{env.APP_NAME}}_v${{needs.shared-resources.outputs.app_version}}_${{matrix.runtime_id}}"
|
||||
path: ${{steps.publish-package.outputs.PACKAGE_PATH}}
|
||||
if-no-files-found: error
|
||||
retention-days: 30
|
||||
|
||||
windows-generate-msixbundle:
|
||||
name: Bundle MSIX packages
|
||||
needs: [shared-resources, windows-sideload-packages]
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Clean bundle workspace
|
||||
run: |
|
||||
Remove-Item -Recurse -Force "${{github.workspace}}\bundle-input" -ErrorAction SilentlyContinue
|
||||
Remove-Item -Recurse -Force "${{github.workspace}}\bundle-output" -ErrorAction SilentlyContinue
|
||||
|
||||
- name: Download x64 artifact
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: "${{env.APP_NAME}}_v${{needs.shared-resources.outputs.app_version}}_win-x64"
|
||||
path: ${{github.workspace}}\bundle-input
|
||||
|
||||
- name: Download arm64 artifact
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: "${{env.APP_NAME}}_v${{needs.shared-resources.outputs.app_version}}_win-arm64"
|
||||
path: ${{github.workspace}}\bundle-input
|
||||
|
||||
- name: Create MSIX bundle
|
||||
id: bundle
|
||||
run: |
|
||||
$appVersion = "${{needs.shared-resources.outputs.app_version}}.0"
|
||||
$inputDir = "${{github.workspace}}\bundle-input"
|
||||
$outputDir = "${{github.workspace}}\bundle-output"
|
||||
New-Item -ItemType Directory -Force -Path $outputDir | Out-Null
|
||||
# Locate makeappx.exe from the latest installed Windows 10 SDK
|
||||
$sdkRoot = "C:\Program Files (x86)\Windows Kits\10\bin"
|
||||
$makeAppx = Get-ChildItem -Path $sdkRoot -Recurse -Filter makeappx.exe -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.FullName -match '\\x64\\makeappx\.exe$' } |
|
||||
Sort-Object FullName -Descending | Select-Object -First 1
|
||||
if (-not $makeAppx) { throw "makeappx.exe not found under $sdkRoot" }
|
||||
Write-Host "Using makeappx: $($makeAppx.FullName)"
|
||||
Get-ChildItem $inputDir -Filter *.msix | ForEach-Object { Write-Host "Input: $($_.FullName)" }
|
||||
$bundlePath = "$outputDir\${{env.APP_NAME}}_v${{needs.shared-resources.outputs.app_version}}.msixbundle"
|
||||
& $makeAppx.FullName bundle /d $inputDir /p $bundlePath /bv $appVersion /o
|
||||
if ($LASTEXITCODE -ne 0) { throw "makeappx bundle failed with exit code $LASTEXITCODE" }
|
||||
|
||||
echo "BUNDLE_PATH=$bundlePath" >> $env:GITHUB_OUTPUT
|
||||
|
||||
# Entra ID App Registration (Akeyless OIDC Provider) > Certificates and Secrets > Federated Credentials
|
||||
- name: Azure login using OIDC via GitHub
|
||||
uses: azure/login@v3
|
||||
id: azlogin
|
||||
with:
|
||||
client-id: ${{env.SERVICE_PRINCIPAL_CLIENT_ID}}
|
||||
tenant-id: ${{env.SERVICE_PRINCIPAL_TENANT_ID}}
|
||||
subscription-id: ${{env.SERVICE_PRINCIPAL_SUBSCRIPTION_ID}}
|
||||
|
||||
- name: Sign MSIX bundle
|
||||
uses: azure/trusted-signing-action@v1.2.0
|
||||
with:
|
||||
endpoint: ${{env.SIGNING_ACCT_ENDPOINT_URL}}
|
||||
signing-account-name: ${{env.SIGNING_ACCT_NAME}}
|
||||
certificate-profile-name: ${{env.SIGNING_ACCT_CERT_PROFILE}}
|
||||
timestamp-rfc3161: http://timestamp.acs.microsoft.com
|
||||
timestamp-digest: SHA256
|
||||
file-digest: SHA256
|
||||
files: ${{steps.bundle.outputs.BUNDLE_PATH}}
|
||||
exclude-azure-cli-credential: false
|
||||
exclude-environment-credential: true
|
||||
exclude-workload-identity-credential: true
|
||||
exclude-managed-identity-credential: true
|
||||
exclude-shared-token-cache-credential: true
|
||||
exclude-visual-studio-credential: true
|
||||
exclude-visual-studio-code-credential: true
|
||||
exclude-azure-powershell-credential: true
|
||||
exclude-azure-developer-cli-credential: true
|
||||
exclude-interactive-browser-credential: true
|
||||
|
||||
- name: Upload MSIX bundle artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: "${{env.APP_NAME}}_v${{needs.shared-resources.outputs.app_version}}_signed-windows.msixbundle"
|
||||
path: ${{steps.bundle.outputs.BUNDLE_PATH}}
|
||||
if-no-files-found: error
|
||||
retention-days: 30
|
||||
|
||||
|
||||
# ********************************************************************************** #
|
||||
# Windows (Store - msixupload) #
|
||||
# ********************************************************************************** #
|
||||
windows-store:
|
||||
name: Build Windows (Store Upload)
|
||||
runs-on: windows-latest
|
||||
needs: shared-resources
|
||||
if: ${{ success() && needs.shared-resources.outputs.app_version != '' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
dotnet-version: ${{env.SDK_VERSION}}
|
||||
|
||||
- name: Add msbuild to PATH
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
|
||||
- name: Install MAUI Workloads
|
||||
run: dotnet workload install maui --source https://api.nuget.org/v3/index.json
|
||||
|
||||
- name: Set Telerik NuGet Credentials
|
||||
run: dotnet nuget update source 'Telerik_v3_Feed' -s 'https://nuget.telerik.com/v3/index.json' -u 'api-key' -p "${{secrets.TELERIK_NUGET_KEY}}" --configfile '${{env.NUGET_CONFIG_PATH}}' --store-password-in-clear-text
|
||||
|
||||
- name: Restore NuGet packages
|
||||
run: dotnet restore ${{env.PROJECT_PATH}} --configfile ${{env.NUGET_CONFIG_PATH}}
|
||||
|
||||
- name: Update manifest for store build
|
||||
run: |
|
||||
[xml]$manifest = Get-Content '${{env.PROJECT_DIRECTORY}}\Platforms\Windows\Package.appxmanifest'
|
||||
$manifest.Package.Identity.Version = "${{needs.shared-resources.outputs.app_version}}.0"
|
||||
$manifest.Save('${{env.PROJECT_DIRECTORY}}\Platforms\Windows\Package.appxmanifest')
|
||||
|
||||
- name: Build Maui WinUI project
|
||||
run: dotnet publish ${{env.PROJECT_PATH}} -c Release -f ${{env.NET_TFM}}-windows10.0.19041.0 -p:AppxPackageSigningEnabled=false -p:AppxSymbolPackageEnabled=false -p:UapAppxPackageBuildMode=StoreUpload -p:AppxBundle=Always "-p:AppxBundlePlatforms=x64|arm64" -p:PlatformTarget=AnyCPU
|
||||
|
||||
- name: Publish build artifacts
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: "${{env.APP_NAME}}_v${{needs.shared-resources.outputs.app_version}}_storeupload-windows"
|
||||
path: "**/*.msixupload"
|
||||
if-no-files-found: error
|
||||
retention-days: 60
|
||||
|
||||
|
||||
# ********************************************************************************** #
|
||||
# MacCatalyst #
|
||||
# ********************************************************************************** #
|
||||
maccatalyst:
|
||||
name: Build MacCatalyst (Signed & Notiarized)
|
||||
runs-on: macos-26 # https://github.com/actions/runner-images#available-images
|
||||
needs: shared-resources
|
||||
if: ${{ success() && needs.shared-resources.outputs.app_version != '' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: maxim-lobanov/setup-xcode@v1
|
||||
with:
|
||||
xcode-version: ${{env.XCODE_VERSION}}
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
dotnet-version: ${{env.SDK_VERSION}}
|
||||
|
||||
- name: Install MAUI Workloads
|
||||
run: dotnet workload install maui --source https://api.nuget.org/v3/index.json
|
||||
|
||||
- name: Set Telerik NuGet Credentials
|
||||
run: dotnet nuget update source 'Telerik_v3_Feed' -s 'https://nuget.telerik.com/v3/index.json' -u 'api-key' -p "${{secrets.TELERIK_NUGET_KEY}}" --configfile '${{env.NUGET_CONFIG_PATH}}' --store-password-in-clear-text
|
||||
|
||||
- name: Restore NuGet packages
|
||||
run: dotnet restore ${{env.PROJECT_PATH}} --configfile ${{env.NUGET_CONFIG_PATH}}
|
||||
|
||||
- name: Import Developer ID Installer Certificates
|
||||
uses: Apple-Actions/import-codesign-certs@v7
|
||||
with:
|
||||
p12-file-base64: "${{secrets.APPLE_DEVELOPER_ID_INSTALLER_CERT_BASE64}}"
|
||||
p12-password: "${{secrets.APPLE_DEVELOPER_ID_INSTALLER_CERT_PASSWORD}}"
|
||||
keychain: installer_signing_temp
|
||||
|
||||
- name: Import Developer ID Application Certificates
|
||||
uses: Apple-Actions/import-codesign-certs@v7
|
||||
with:
|
||||
p12-file-base64: "${{secrets.APPLE_DEVELOPER_ID_APPLICATION_CERT_BASE64}}"
|
||||
p12-password: "${{secrets.APPLE_DEVELOPER_ID_APPLICATION_CERT_PASSWORD}}"
|
||||
keychain: application_signing_temp
|
||||
|
||||
# Each import-codesign-certs call rewrites the keychain search list. The second import step (Application cert) drops the first (Installer) keychain, so product build cannot find the "Developer ID Installer" identity. This step re-adds both keychains explicitly before any signing occurs.
|
||||
- name: Ensure both signing keychains are in the search list
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
security list-keychains -d user -s "$HOME/Library/Keychains/installer_signing_temp.keychain-db" "$HOME/Library/Keychains/application_signing_temp.keychain-db" "$HOME/Library/Keychains/login.keychain-db"
|
||||
echo "Keychain search list:"
|
||||
security list-keychains -d user
|
||||
|
||||
# Finally make sure both certs are available before we build
|
||||
- name: Verify Developer ID identities are available
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
APPLE_DEV_ID_APP_CERT_NAME="${{env.APPLE_DEV_ID_APP_CERT_NAME}}"
|
||||
APPLE_DEV_ID_INSTALLER_CERT_NAME="${{env.APPLE_DEV_ID_INSTALLER_CERT_NAME}}"
|
||||
|
||||
security find-identity -v -p codesigning
|
||||
security find-certificate -a -c "$APPLE_DEV_ID_INSTALLER_CERT_NAME" || true
|
||||
|
||||
if ! security find-identity -v -p codesigning | grep -F "$APPLE_DEV_ID_APP_CERT_NAME" >/dev/null; then
|
||||
echo "Missing Developer ID Application identity: $APPLE_DEV_ID_APP_CERT_NAME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! security find-certificate -a -c "$APPLE_DEV_ID_INSTALLER_CERT_NAME" >/dev/null; then
|
||||
echo "Missing Developer ID Installer certificate: $APPLE_DEV_ID_INSTALLER_CERT_NAME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Build and sign MacCatalyst artifacts
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cd "$GITHUB_WORKSPACE"
|
||||
|
||||
if [[ ! -f "$PROJECT_PATH" ]]; then
|
||||
echo "Project file not found: $PROJECT_PATH"
|
||||
echo "Current directory: $(pwd)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$ARTIFACTS_DIR"
|
||||
|
||||
echo "Cleaning project..."
|
||||
dotnet clean "$PROJECT_PATH" -c "$CONFIGURATION" -f "$TFM"
|
||||
|
||||
publish_args=(
|
||||
"$PROJECT_PATH"
|
||||
-c "$CONFIGURATION"
|
||||
-f "$TFM"
|
||||
"-p:CodesignKey=\"$CODESIGN_KEY\""
|
||||
"-p:ApplicationVersion=$APP_VERSION"
|
||||
"-p:ApplicationDisplayVersion=$APP_VERSION"
|
||||
-p:UseHardenedRuntime=true
|
||||
)
|
||||
|
||||
echo "Publishing project..."
|
||||
dotnet publish "${publish_args[@]}"
|
||||
|
||||
if [[ ! -d "$APP_BUNDLE_PATH" ]]; then
|
||||
echo "Expected app bundle not found at $APP_BUNDLE_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Verifying app signature..."
|
||||
codesign -dv --verbose=2 "$APP_BUNDLE_PATH" >/dev/null 2>&1
|
||||
|
||||
echo "Creating signed app zip and installer pkg..."
|
||||
rm -f "$SIGNED_ZIP_PATH" "$SIGNED_PKG_PATH"
|
||||
ditto -c -k --sequesterRsrc --keepParent "$APP_BUNDLE_PATH" "$SIGNED_ZIP_PATH"
|
||||
productbuild --component "$APP_BUNDLE_PATH" /Applications --sign "$INSTALLER_SIGN_ID" "$SIGNED_PKG_PATH"
|
||||
|
||||
echo "Done. Signed artifacts:"
|
||||
echo "- $SIGNED_PKG_PATH"
|
||||
echo "- $SIGNED_ZIP_PATH"
|
||||
env:
|
||||
PROJECT_PATH: "${{env.PROJECT_PATH}}"
|
||||
TFM: "${{env.NET_TFM}}-maccatalyst"
|
||||
CONFIGURATION: "Release"
|
||||
APP_VERSION: "${{needs.shared-resources.outputs.app_version}}"
|
||||
ARTIFACTS_DIR: "${{env.MAC_ARTIFACTS_PATH}}"
|
||||
APP_BUNDLE_PATH: "${{env.MAC_APP_BUNDLE_PATH}}"
|
||||
CODESIGN_KEY: "${{env.APPLE_DEV_ID_APP_CERT_NAME}}"
|
||||
INSTALLER_SIGN_ID: "${{ env.APPLE_DEV_ID_INSTALLER_CERT_NAME}}"
|
||||
SIGNED_ZIP_PATH: "$ARTIFACTS_DIR/${{env.MAC_PACKAGE_NAME}}-Release-signed.zip"
|
||||
SIGNED_PKG_PATH: "$ARTIFACTS_DIR/${{env.MAC_PACKAGE_NAME}}-Release-signed.pkg"
|
||||
|
||||
- name: Notarize and staple MacCatalyst artifacts
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cd "$GITHUB_WORKSPACE"
|
||||
|
||||
if [[ -z "$APPLE_NOTARY_APPLE_ID" || -z "$APPLE_NOTARY_APP_PASSWORD" || -z "$APPLE_NOTARY_TEAM_ID" ]]; then
|
||||
echo "Missing notarization credentials."
|
||||
echo "Set APPLE_NOTARY_APPLE_ID, APPLE_NOTARY_APP_PASSWORD, and APPLE_NOTARY_TEAM_ID."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -d "$APP_BUNDLE_PATH" ]]; then
|
||||
echo "Expected app bundle not found at $APP_BUNDLE_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$SIGNED_PKG_PATH" || ! -f "$SIGNED_ZIP_PATH" ]]; then
|
||||
echo "Expected signed artifacts not found in $ARTIFACTS_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Submitting pkg for notarization..."
|
||||
pkg_submit_json="$(xcrun notarytool submit "$SIGNED_PKG_PATH" --apple-id "$APPLE_NOTARY_APPLE_ID" --team-id "$APPLE_NOTARY_TEAM_ID" --password "$APPLE_NOTARY_APP_PASSWORD" --wait --output-format json)"
|
||||
echo "$pkg_submit_json"
|
||||
if ! grep -Eq '"status"[[:space:]]*:[[:space:]]*"Accepted"' <<< "$pkg_submit_json"; then
|
||||
echo "Notarization failed for pkg."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Stapling and validating pkg..."
|
||||
xcrun stapler staple "$SIGNED_PKG_PATH"
|
||||
xcrun stapler validate "$SIGNED_PKG_PATH"
|
||||
|
||||
echo "Submitting signed app zip for notarization..."
|
||||
zip_submit_json="$(xcrun notarytool submit "$SIGNED_ZIP_PATH" --apple-id "$APPLE_NOTARY_APPLE_ID" --team-id "$APPLE_NOTARY_TEAM_ID" --password "$APPLE_NOTARY_APP_PASSWORD" --wait --output-format json)"
|
||||
echo "$zip_submit_json"
|
||||
if ! grep -Eq '"status"[[:space:]]*:[[:space:]]*"Accepted"' <<< "$zip_submit_json"; then
|
||||
echo "Notarization failed for app zip."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Stapling and validating app..."
|
||||
xcrun stapler staple "$APP_BUNDLE_PATH"
|
||||
xcrun stapler validate "$APP_BUNDLE_PATH"
|
||||
|
||||
# Recreate the final distributable zip from the stapled app.
|
||||
ditto -c -k --sequesterRsrc --keepParent "$APP_BUNDLE_PATH" "$NOTARIZED_ZIP_PATH"
|
||||
|
||||
echo "Gatekeeper checks..."
|
||||
spctl -a -t exec -vv "$APP_BUNDLE_PATH"
|
||||
spctl -a -t install -vv "$SIGNED_PKG_PATH"
|
||||
|
||||
echo "Done. Artifacts:"
|
||||
echo "- $SIGNED_PKG_PATH"
|
||||
echo "- $NOTARIZED_ZIP_PATH"
|
||||
env:
|
||||
ARTIFACTS_DIR: "${{env.MAC_ARTIFACTS_PATH}}"
|
||||
APP_BUNDLE_PATH: "${{env.MAC_APP_BUNDLE_PATH}}"
|
||||
APPLE_NOTARY_APPLE_ID: "${{secrets.APPLE_NOTARY_APPLE_ID}}"
|
||||
APPLE_NOTARY_APP_PASSWORD: "${{secrets.APPLE_NOTARY_APP_PASSWORD}}"
|
||||
APPLE_NOTARY_TEAM_ID: "${{env.APPLE_NOTARY_TEAM_ID}}"
|
||||
SIGNED_ZIP_PATH: "${{env.MAC_ARTIFACTS_PATH}}/${{env.MAC_PACKAGE_NAME}}-Release-signed.zip"
|
||||
NOTARIZED_ZIP_PATH: "${{env.MAC_ARTIFACTS_PATH}}/${{env.MAC_PACKAGE_NAME}}-Release-notarized.zip"
|
||||
SIGNED_PKG_PATH: "${{env.MAC_ARTIFACTS_PATH}}/${{env.MAC_PACKAGE_NAME}}-Release-signed.pkg"
|
||||
|
||||
- name: Publish MacCatalyst build artifacts
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: "${{env.APP_NAME}}_v${{needs.shared-resources.outputs.app_version}}_signed-maccatalyst"
|
||||
path: ${{env.MAC_ARTIFACTS_PATH}}/${{env.MAC_PACKAGE_NAME}}-Release-signed.pkg
|
||||
if-no-files-found: error
|
||||
retention-days: 30
|
||||
|
||||
|
||||
# ********************************************************************************** #
|
||||
# iOS #
|
||||
# ********************************************************************************** #
|
||||
ios:
|
||||
name: Build iOS (${{matrix.distribution_name}})
|
||||
runs-on: macos-26 # https://github.com/actions/runner-images#available-images
|
||||
needs: shared-resources
|
||||
if: ${{ success() && needs.shared-resources.outputs.app_version != '' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- distribution_name: Store Upload IPA
|
||||
artifact_suffix: storeupload-ios
|
||||
provisioning_profile: MauiDemo_AppStore_Distribution
|
||||
provisioning_profile_type: IOS_APP_STORE
|
||||
rid: ios-arm64
|
||||
- distribution_name: Ad Hoc Sideload IPA
|
||||
artifact_suffix: sideload-ios
|
||||
provisioning_profile: MauiDemo_AdHoc_Distribution
|
||||
provisioning_profile_type: IOS_APP_ADHOC
|
||||
rid: ios-arm64
|
||||
env:
|
||||
APPLE_PROV_PROFILE: ${{matrix.provisioning_profile}}
|
||||
APPLE_PROV_PROFILE_TYPE: ${{matrix.provisioning_profile_type}}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: maxim-lobanov/setup-xcode@v1
|
||||
with:
|
||||
xcode-version: ${{env.XCODE_VERSION}}
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
dotnet-version: ${{env.SDK_VERSION}}
|
||||
|
||||
- name: Install MAUI Workloads
|
||||
run: dotnet workload install maui --source https://api.nuget.org/v3/index.json
|
||||
|
||||
- name: Set Telerik NuGet Credentials
|
||||
run: dotnet nuget update source 'Telerik_v3_Feed' -s 'https://nuget.telerik.com/v3/index.json' -u 'api-key' -p "${{secrets.TELERIK_NUGET_KEY}}" --configfile '${{env.NUGET_CONFIG_PATH}}' --store-password-in-clear-text
|
||||
|
||||
- name: Restore NuGet packages
|
||||
run: dotnet restore ${{env.PROJECT_PATH}} --configfile ${{env.NUGET_CONFIG_PATH}}
|
||||
|
||||
# Docs https://github.com/Apple-Actions/import-codesign-certs
|
||||
- name: Import Code-Signing Certificates
|
||||
uses: Apple-Actions/import-codesign-certs@v7
|
||||
with:
|
||||
p12-file-base64: "${{secrets.APPLE_DISTRIBUTION_CERT_BASE64}}"
|
||||
p12-password: "${{secrets.APPLE_DISTRIBUTION_CERT_PASSWORD}}"
|
||||
|
||||
# Docs https://github.com/Apple-Actions/download-provisioning-profiles
|
||||
- id: provisioning-profiles
|
||||
uses: Apple-Actions/download-provisioning-profiles@v6
|
||||
with:
|
||||
profile-type: "${{env.APPLE_PROV_PROFILE_TYPE}}"
|
||||
bundle-id: "${{env.APPLE_APP_ID}}"
|
||||
issuer-id: "${{secrets.APPSTORE_API_ISSUER_ID}}"
|
||||
api-key-id: "${{secrets.APPSTORE_API_KEY_ID}}"
|
||||
api-private-key: "${{secrets.APPSTORE_API_PRIVATE_KEY}}"
|
||||
|
||||
- name: Verify provisioning profile
|
||||
run: |
|
||||
$profiles = '${{steps.provisioning-profiles.outputs.profiles}}' | ConvertFrom-Json
|
||||
$profile = $profiles | Where-Object { $_.name -eq $env:APPLE_PROV_PROFILE -and $_.type -eq $env:APPLE_PROV_PROFILE_TYPE } | Select-Object -First 1
|
||||
|
||||
if ($null -eq $profile) {
|
||||
$profiles | Format-Table -AutoSize | Out-String | Write-Host
|
||||
throw "Provisioning profile '$env:APPLE_PROV_PROFILE' with type '$env:APPLE_PROV_PROFILE_TYPE' was not downloaded."
|
||||
}
|
||||
|
||||
- name: Verify iOS signing identity is available
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
security find-identity -v -p codesigning
|
||||
if ! security find-identity -v -p codesigning | grep -F "Apple Distribution" >/dev/null; then
|
||||
echo "Missing Apple Distribution identity"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Docs https://learn.microsoft.com/en-us/dotnet/maui/ios/deployment/publish-cli?view=net-maui-9.0
|
||||
- name: Publish MAUI iOS IPA
|
||||
run: |
|
||||
# Query the actual signing identity to avoid comma parsing issues
|
||||
$identityOutput = security find-identity -v -p codesigning | Select-String "Apple Distribution"
|
||||
if (-not $identityOutput) { throw "No Apple Distribution identity found in keychain" }
|
||||
$codesignKey = [regex]::Match($identityOutput.Line, '"(?<name>Apple Distribution:[^"]+)"').Groups['name'].Value
|
||||
if (-not $codesignKey) { throw "Could not parse Apple Distribution identity from keychain output" }
|
||||
Write-Host "Using codesign key: $codesignKey"
|
||||
$quotedCodesignKey = '"' + $codesignKey + '"'
|
||||
|
||||
$publishArgs = @(
|
||||
'publish'
|
||||
'${{env.PROJECT_PATH}}'
|
||||
'-f', '${{env.NET_TFM}}-ios'
|
||||
'-c', 'Release'
|
||||
'-p:ArchiveOnBuild=true'
|
||||
'-p:RuntimeIdentifier=${{matrix.rid}}'
|
||||
'-p:MtouchLink=SdkOnly'
|
||||
'-p:ApplicationId=${{env.APPLE_APP_ID}}'
|
||||
'-p:ApplicationVersion=${{needs.shared-resources.outputs.app_version}}'
|
||||
'-p:CodesignProvision=${{env.APPLE_PROV_PROFILE}}'
|
||||
"-p:CodesignKey=$quotedCodesignKey"
|
||||
)
|
||||
& dotnet @publishArgs
|
||||
if ($LASTEXITCODE -ne 0) { throw "dotnet publish failed with exit code $LASTEXITCODE" }
|
||||
|
||||
- name: Publish iOS build artifacts
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: "${{env.APP_NAME}}_v${{needs.shared-resources.outputs.app_version}}_${{matrix.artifact_suffix}}"
|
||||
path: "${{env.PROJECT_DIRECTORY}}/bin/Release/${{env.NET_TFM}}-ios/${{matrix.rid}}/publish/*.ipa"
|
||||
if-no-files-found: error
|
||||
retention-days: 60
|
||||
|
||||
|
||||
# ********************************************************************************** #
|
||||
# GitHub Release #
|
||||
# ********************************************************************************** #
|
||||
# create-release:
|
||||
# name: Create GitHub Release
|
||||
# runs-on: ubuntu-latest
|
||||
# needs: [shared-resources, android, windows-sideload-packages, windows-generate-msixbundle, windows-store, maccatalyst, ios]
|
||||
# steps:
|
||||
# - name: Download all artifacts
|
||||
# uses: actions/download-artifact@v8
|
||||
# with:
|
||||
# path: release-artifacts
|
||||
|
||||
# - name: List downloaded artifacts
|
||||
# shell: bash
|
||||
# run: find release-artifacts -type f | sort
|
||||
|
||||
# - name: Prepare release files
|
||||
# shell: bash
|
||||
# run: |
|
||||
# set -euo pipefail
|
||||
# VER="${{needs.shared-resources.outputs.app_version}}"
|
||||
# PREFIX="${{env.APP_NAME}}_v${VER}"
|
||||
# mkdir -p release-upload
|
||||
# copy_one() {
|
||||
# local artifact_dir="$1"
|
||||
# local pattern="$2"
|
||||
# local destination="$3"
|
||||
# local -a matches=()
|
||||
# if [[ ! -d "$artifact_dir" ]]; then
|
||||
# echo "Expected artifact directory not found: $artifact_dir" >&2
|
||||
# exit 1
|
||||
# fi
|
||||
# mapfile -d '' matches < <(find "$artifact_dir" -type f -name "$pattern" -print0 | sort -z)
|
||||
# if [[ ${#matches[@]} -ne 1 ]]; then
|
||||
# echo "Expected exactly one match for '$pattern' under '$artifact_dir', found ${#matches[@]}." >&2
|
||||
# find "$artifact_dir" -type f | sort >&2
|
||||
# exit 1
|
||||
# fi
|
||||
# cp -- "${matches[0]}" "$destination"
|
||||
# }
|
||||
# # Android
|
||||
# copy_one "release-artifacts/${PREFIX}_signed-android" "*-Signed.apk" "release-upload/${PREFIX}_android-signed.apk"
|
||||
# copy_one "release-artifacts/${PREFIX}_signed-android" "*-Signed.aab" "release-upload/${PREFIX}_android-signed.aab"
|
||||
# # Windows msixbundle (signed)
|
||||
# copy_one "release-artifacts/${PREFIX}_signed-windows.msixbundle" "*.msixbundle" "release-upload/${PREFIX}_windows.msixbundle"
|
||||
# # Windows Store
|
||||
# copy_one "release-artifacts/${PREFIX}_storeupload-windows" "*.msixupload" "release-upload/${PREFIX}_msstore.msixupload"
|
||||
# # MacCatalyst
|
||||
# copy_one "release-artifacts/${PREFIX}_signed-maccatalyst" "*.pkg" "release-upload/${PREFIX}_mac.pkg"
|
||||
# # iOS
|
||||
# copy_one "release-artifacts/${PREFIX}_ios-adhoc" "*.ipa" "release-upload/${PREFIX}_ios-adhoc.ipa"
|
||||
# copy_one "release-artifacts/${PREFIX}_ios-store" "*.ipa" "release-upload/${PREFIX}_ios-store.ipa"
|
||||
# echo "Files prepared for release:"
|
||||
# ls -lh release-upload/
|
||||
|
||||
# - name: Create GitHub Release
|
||||
# uses: softprops/action-gh-release@v3.0.0
|
||||
# with:
|
||||
# tag_name: "v${{needs.shared-resources.outputs.app_version}}"
|
||||
# name: "${{env.APP_NAME}} v${{needs.shared-resources.outputs.app_version}}"
|
||||
# draft: false
|
||||
# prerelease: false
|
||||
# generate_release_notes: true
|
||||
# files: release-upload/*
|
||||
@@ -0,0 +1,49 @@
|
||||
# This example shows you how you can use the named environment variables in the nuget.config file to set the credentials, for more information see https://github.com/LanceMcCarthy/DevOpsExamples#github-actions-using-secrets-to-set-environment-variables
|
||||
name: WinForms (.NET Framework)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- "winforms/*"
|
||||
paths:
|
||||
- 'src/WinForms/**/*'
|
||||
- '.github/workflows/main_build-winforms.yml'
|
||||
|
||||
env:
|
||||
TELERIK_USERNAME: "api-key" # Variable name used in the nuget.config file
|
||||
TELERIK_PASSWORD: ${{secrets.TELERIK_NUGET_KEY}} # Variable name used in the nuget.config file
|
||||
TELERIK_LICENSE: ${{secrets.TELERIK_LICENSE_KEY}} # Used when compiling the project
|
||||
CSPROJ_PATH: "src/WinForms/MyWinFormsApp/MyWinFormsApp.csproj"
|
||||
NUGETCONFIG_PATH: "src/NuGet.Config"
|
||||
|
||||
jobs:
|
||||
# A job that builds a .NET Framework WPF application using Telerik UI for WinForms
|
||||
build_desktop:
|
||||
runs-on: windows-latest # WinForms apps must be built on Windows runners
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [Release]
|
||||
platform: [x86, x64]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '10.0.x'
|
||||
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
# We use the dotnet CLI (instead of nuget CLI) to restore the nuget packages before using msbuild
|
||||
- name: NuGet Restore
|
||||
run: dotnet restore ${{env.CSPROJ_PATH}} --configfile ${{env.NUGETCONFIG_PATH}} --runtime win-${{matrix.platform}}
|
||||
|
||||
# Use msbuild to compile the .NET Framework WinForms project
|
||||
- name: Build the WinForms application
|
||||
run: msbuild ${{env.CSPROJ_PATH}} /t:Restore /p:Configuration=${{matrix.configuration}} /p:RuntimeIdentifier=win-${{matrix.platform}}
|
||||
@@ -0,0 +1,57 @@
|
||||
name: WinUI3
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- "winui/*"
|
||||
paths:
|
||||
- 'src/WinUI/**/*'
|
||||
- '.github/workflows/main_build-winui.yml'
|
||||
|
||||
env:
|
||||
TELERIK_USERNAME: "api-key" # Used by the nuget.config file
|
||||
TELERIK_PASSWORD: ${{secrets.TELERIK_NUGET_KEY}} # Used by the nuget.config file
|
||||
SOLUTION_NAME: "src/WinUI/MyDemo.sln"
|
||||
NUGETCONFIG_PATH: "src/NuGet.Config"
|
||||
|
||||
jobs:
|
||||
build-windows:
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '10.0.x'
|
||||
|
||||
- name: Add msbuild to PATH
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
- name: Restore NuGet packages
|
||||
shell: pwsh
|
||||
run: dotnet restore ${{env.SOLUTION_NAME}} --configfile ${{env.NUGETCONFIG_PATH}}
|
||||
|
||||
# Restore the application to populate the obj folder with RuntimeIdentifiers
|
||||
- name: Restore RIDs
|
||||
run: msbuild ${{env.SOLUTION_NAME}} /t:Restore /p:Configuration=Release
|
||||
|
||||
- name: Build and Create MSIX
|
||||
run: |
|
||||
msbuild ${{env.SOLUTION_NAME}} `
|
||||
/p:Configuration=Release `
|
||||
/p:Platform=x64 `
|
||||
/p:AppxBundlePlatforms="x64|arm64" `
|
||||
/p:UapAppxPackageBuildMode=CI `
|
||||
/p:AppxBundle=Never `
|
||||
/p:AppxPackageDir="${{github.workspace}}/AppPackages" `
|
||||
/p:GenerateAppxPackageOnBuild=true `
|
||||
/p:AppxPackageSigningEnabled=false `
|
||||
/p:SelfContained=true
|
||||
env:
|
||||
TELERIK_LICENSE: ${{secrets.TELERIK_LICENSE_KEY}}
|
||||
@@ -0,0 +1,48 @@
|
||||
# This example shows you how you can use the named environment variables in the nuget.config file to set the credentials
|
||||
name: WPF (.NET Framework)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- "wpf/*"
|
||||
paths:
|
||||
- 'src/Wpf/**/*'
|
||||
- '.github/workflows/main_build-wpf.yml'
|
||||
|
||||
env:
|
||||
TELERIK_USERNAME: "api-key" # Variable name used in the nuget.config file
|
||||
TELERIK_PASSWORD: ${{secrets.TELERIK_NUGET_KEY}} # Variable name used in the nuget.config file
|
||||
TELERIK_LICENSE: ${{secrets.TELERIK_LICENSE_KEY}} # Used when compiling the project
|
||||
CSPROJ_PATH: "src/Wpf/MyWpfApp/MyWpfApp.csproj"
|
||||
NUGETCONFIG_PATH: "src/NuGet.Config"
|
||||
|
||||
jobs:
|
||||
build_desktop:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [Release]
|
||||
platform: [x86, x64]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install .NET SDK
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '10.0.x'
|
||||
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
# We use the dotnet CLI (instead of nuget.exe) to restore the nuget packages before using msbuild
|
||||
- name: NuGet Restore
|
||||
run: dotnet restore ${{env.CSPROJ_PATH}} --configfile ${{env.NUGETCONFIG_PATH}} --runtime win-${{matrix.platform}}
|
||||
|
||||
# Use msbuild to compile the .NET Framework WPF project
|
||||
- name: Build the WPF application
|
||||
run: msbuild ${{env.CSPROJ_PATH}} /t:Restore /p:Configuration=${{matrix.configuration}} /p:RuntimeIdentifier=${{matrix.platform}}
|
||||
@@ -0,0 +1,173 @@
|
||||
name: ASP.NET Core (with Reporting) - Docker
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'src/AspNetCore/**/*'
|
||||
|
||||
env:
|
||||
WORKING_DIRECTORY: "src/AspNetCore/MyAspNetCoreApp"
|
||||
TARGET_PLATFORMS: "linux/amd64,linux/arm64"
|
||||
|
||||
jobs:
|
||||
#################### Example 1 ##########################
|
||||
# Dockerfile build and publish to Docker Hub
|
||||
# - Uses mcr.microsoft.com/dotnet/aspnet base image
|
||||
# - Webook to automatically redeploy stack in Portainer
|
||||
#########################################################
|
||||
dockerhub_msftbase_build:
|
||||
name: Microsoft Base - Publish to Docker Hub
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CONTAINER_REPOSITORY: "lancemccarthy/aspnetcore-reporting-from-msftbase"
|
||||
DOCKERFILE_PATH: "src/AspNetCore/MyAspNetCoreApp/Dockerfile_MSRuntimeBase"
|
||||
CONTAINER_REGISTRY: "docker.io"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up QEMU for multi-arch support
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Get package metadata from Docker Hub
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{env.CONTAINER_REGISTRY}}/${{env.CONTAINER_REPOSITORY}}
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{secrets.DOCKER_HUB_USERNAME}}
|
||||
password: ${{secrets.DOCKER_HUB_PAT}}
|
||||
|
||||
- name: Build and push to Docker Hub
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: ${{env.DOCKERFILE_PATH}}
|
||||
context: ${{env.WORKING_DIRECTORY}}
|
||||
platforms: ${{env.TARGET_PLATFORMS}}
|
||||
push: true
|
||||
secrets: |
|
||||
telerik-nuget-key=${{secrets.TELERIK_NUGET_KEY}}
|
||||
telerik-license-key=${{secrets.TELERIK_LICENSE_KEY}}
|
||||
tags: ${{steps.meta.outputs.tags}}
|
||||
|
||||
- name: Trigger Portainer to pull images and redeploy the stack
|
||||
run: curl -X POST ${{secrets.PORTAINER_WEBHOOK_ASPNETCORE}}
|
||||
|
||||
|
||||
#################### Example 2 ##########################
|
||||
# Dockerfile build and publish to Docker Hub
|
||||
# - Uses a CentOS Base Image
|
||||
# - Webook to automatically redeploy stack in Portainer
|
||||
#########################################################
|
||||
dockerhub_centosbase_build:
|
||||
name: CentOS Base - Publish to Docker Hub
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CONTAINER_REPOSITORY: "lancemccarthy/aspnetcore-reporting-from-centosbase"
|
||||
DOCKERFILE_PATH: "src/AspNetCore/MyAspNetCoreApp/Dockerfile_CentOS"
|
||||
CONTAINER_REGISTRY: "docker.io"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up QEMU for multi-arch support
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Get package metadata from Docker Hub
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{env.CONTAINER_REGISTRY}}/${{env.CONTAINER_REPOSITORY}}
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{secrets.DOCKER_HUB_USERNAME}}
|
||||
password: ${{secrets.DOCKER_HUB_PAT}}
|
||||
|
||||
- name: Build and push to Docker Hub
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: ${{env.DOCKERFILE_PATH}}
|
||||
context: ${{env.WORKING_DIRECTORY}}
|
||||
platforms: ${{env.TARGET_PLATFORMS}}
|
||||
push: true
|
||||
secrets: |
|
||||
telerik-nuget-key=${{secrets.TELERIK_NUGET_KEY}}
|
||||
telerik-license-key=${{secrets.TELERIK_LICENSE_KEY}}
|
||||
tags: ${{steps.meta.outputs.tags}}
|
||||
|
||||
# ############################################################################
|
||||
# ghcr.io option
|
||||
# ############################################################################
|
||||
|
||||
# Set worklow permissions for publishing to GitHub Container Registry
|
||||
# permissions:
|
||||
# contents: read
|
||||
# packages: write # to publish to GitHub container registry
|
||||
|
||||
# ghcr_msftbase_build:
|
||||
# name: Microsoft Base - Publish to GitHub Container Registry
|
||||
# runs-on: ubuntu-latest
|
||||
# env:
|
||||
# CONTAINER_REGISTRY: "ghcr.io"
|
||||
# CONTAINER_REPOSITORY: "lancemccarthy/reporting-msft-base"
|
||||
# DOCKERFILE_PATH: "src/AspNetCore/MyAspNetCoreApp/Dockerfile_MSRuntimeBase"
|
||||
# steps:
|
||||
# - name: Checkout
|
||||
# uses: actions/checkout@v6
|
||||
# with:
|
||||
# fetch-depth: 0
|
||||
|
||||
# - name: Set up QEMU
|
||||
# uses: docker/setup-qemu-action@v3
|
||||
|
||||
# - name: Set up Docker Buildx
|
||||
# uses: docker/setup-buildx-action@v3
|
||||
|
||||
# - name: Get package metadata from Docker Hub
|
||||
# id: meta
|
||||
# uses: docker/metadata-action@v5
|
||||
# with:
|
||||
# images: ${{env.CONTAINER_REGISTRY}}/${{env.CONTAINER_REPOSITORY}}
|
||||
|
||||
# - name: Login to DockerHub
|
||||
# uses: docker/login-action@v3
|
||||
# with:
|
||||
# registry: ${{env.CONTAINER_REGISTRY}}
|
||||
# username: ${{secrets.DOCKER_HUB_USERNAME}}
|
||||
# password: ${{secrets.DOCKER_HUB_PAT}}
|
||||
|
||||
# - name: Build and push to Docker Hub
|
||||
# uses: docker/build-push-action@v5
|
||||
# with:
|
||||
# file: ${{env.DOCKERFILE_PATH}}
|
||||
# context: ${{env.WORKING_DIRECTORY}}
|
||||
# platforms: ${{env.TARGET_PLATFORMS}}
|
||||
# push: true
|
||||
# secrets: |
|
||||
# telerik-nuget-key=${{secrets.TELERIK_NUGET_KEY}}
|
||||
# telerik-license-key=${{secrets.TELERIK_LICENSE_KEY}}
|
||||
# tags: ${{steps.meta.outputs.tags}}
|
||||
|
||||
# - name: Delete old Docker images
|
||||
# uses: actions/delete-package-versions@v5
|
||||
# with:
|
||||
# package-name: "myaspnetcoreapp"
|
||||
# package-type: container
|
||||
# min-versions-to-keep: 3
|
||||
# token: ${{secrets.GITHUB_TOKEN}}
|
||||
@@ -0,0 +1,213 @@
|
||||
name: Blazor (with Reporting) - Docker
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'src/Blazor/**/*'
|
||||
|
||||
env:
|
||||
DOTNET_VERSION: "10.0.x"
|
||||
BLAZOR_PROJ_PATH: src/Blazor/MyBlazorApp/MyBlazorApp.csproj
|
||||
NUGET_CONFIG_PATH: src/NuGet.Config
|
||||
CONTAINER_REPOSITORY: "lancemccarthy/myblazorapp"
|
||||
|
||||
# For ghcr.io access
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
#################### Example 1 ##########################
|
||||
# Dockerfile build and publish to Docker Hub
|
||||
# - Webook to automatically redeploy stack in Portainer
|
||||
#########################################################
|
||||
dockerfile_to_dockerhub:
|
||||
name: "Dockerfile Build and Publish"
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CONTAINER_REGISTRY: "docker.io"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Generate tag version
|
||||
id: tag-creator
|
||||
run: |
|
||||
buildDay=`date +%Y.%m.%d`
|
||||
tags="$buildDay.$GITHUB_RUN_NUMBER"
|
||||
echo "VERSION_TAG=$tags" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Get package metadata from Docker Hub
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{env.CONTAINER_REGISTRY}}/${{env.CONTAINER_REPOSITORY}}
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{secrets.DOCKER_HUB_USERNAME}}
|
||||
password: ${{secrets.DOCKER_HUB_PAT}}
|
||||
|
||||
- name: Build and Publish arm64, amd64 Container Images
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: src/Blazor/MyBlazorApp
|
||||
platforms: linux/arm64,linux/amd64
|
||||
push: true
|
||||
secrets: |
|
||||
telerik-nuget-key=${{secrets.TELERIK_NUGET_KEY}}
|
||||
telerik-license-key=${{secrets.TELERIK_LICENSE_KEY}}
|
||||
tags: ${{steps.meta.outputs.tags}}
|
||||
|
||||
# Required because actions/delete-package-versions@v5 does not work with Docker Hub
|
||||
- name: Delete old (untagged) images
|
||||
run: |
|
||||
IMAGE_TAGS=$(curl -s "https://hub.docker.com/v2/repositories/${{env.CONTAINER_REPOSITORY}}/tags/?page_size=100" | jq -r '.results|.[]|.name')
|
||||
for TAGG in $IMAGE_TAGS; do
|
||||
if [[ "$TAGG" == "null" ]]; then
|
||||
docker rmi "${{env.CONTAINER_REPOSITORY}}:$TAGG"
|
||||
curl -s -X DELETE "https://hub.docker.com/v2/repositories/${{env.CONTAINER_REPOSITORY}}/tags/$TAGG/"
|
||||
fi
|
||||
done
|
||||
|
||||
- name: Trigger Portainer to pull images and redeploy the stack
|
||||
run: curl -X POST ${{secrets.PORTAINER_WEBHOOK_BLAZOR}}
|
||||
|
||||
|
||||
#################### Example 2 ##########################
|
||||
# .NET SDK build and publish to ghcr.io
|
||||
############################################################
|
||||
|
||||
# # 2.1 - Build the lancemccarthy/myblazorapp:latest-x64 image
|
||||
# build_x64:
|
||||
# runs-on: ubuntu-latest
|
||||
# name: "[NET SDK] Create x64 image"
|
||||
# outputs:
|
||||
# build_tag: ${{steps.build.outputs.build_tag}}
|
||||
# env:
|
||||
# target_arch: "x64"
|
||||
# CONTAINER_REGISTRY: "ghcr.io"
|
||||
# CONTAINER_BASE_IMAGE: "docker.io/lancemccarthy/skia-aspnet:10.0"
|
||||
# steps:
|
||||
# - name: Checkout
|
||||
# uses: actions/checkout@v6
|
||||
# with:
|
||||
# fetch-depth: 0
|
||||
|
||||
# - name: Setup .NET Core SDK
|
||||
# uses: actions/setup-dotnet@v4
|
||||
# with:
|
||||
# dotnet-version: ${{env.DOTNET_VERSION}}
|
||||
|
||||
# # Needed because dotnet publish -t:PublishContainer uses the CLI (not docker/login-action@v3)
|
||||
# - name: Login to ghcr.io
|
||||
# run: docker login ${{env.CONTAINER_REGISTRY}} -u ${{github.actor}} -p ${{secrets.GITHUB_TOKEN}}
|
||||
|
||||
# - name: Restore NuGet Packages
|
||||
# run: dotnet restore ${{env.BLAZOR_PROJ_PATH}} -r "linux-${{env.target_arch}}"
|
||||
# env:
|
||||
# TELERIK_USERNAME: "api-key"
|
||||
# TELERIK_PASSWORD: ${{secrets.TELERIK_NUGET_KEY}}
|
||||
|
||||
# - name: build the x64 image
|
||||
# id: build
|
||||
# run: |
|
||||
# TAG="latest-${{env.target_arch}}"
|
||||
# dotnet publish ${{env.BLAZOR_PROJ_PATH}} \
|
||||
# -t:PublishContainer \
|
||||
# -p PublishProfile=DefaultContainer \
|
||||
# -p ContainerBaseImage=${{env.CONTAINER_BASE_IMAGE}} \
|
||||
# -p ContainerRegistry="${{env.CONTAINER_REGISTRY}}" \
|
||||
# -p ContainerRepository="${{env.CONTAINER_REPOSITORY}}" \
|
||||
# -p ContainerImageTag="$TAG" \
|
||||
# --arch ${{env.target_arch}} \
|
||||
# --no-restore
|
||||
# echo "build_tag=$TAG" >> $GITHUB_OUTPUT
|
||||
# env:
|
||||
# TELERIK_LICENSE: ${{secrets.TELERIK_LICENSE_KEY}}
|
||||
|
||||
# # Builds the lancemccarthy/myblazorapp:latest-arm64 image
|
||||
# build_arm64:
|
||||
# name: "[NET SDK] Create arm64 image"
|
||||
# runs-on: ubuntu-latest
|
||||
# outputs:
|
||||
# build_tag: ${{steps.build.outputs.build_tag}}
|
||||
# env:
|
||||
# target_arch: "arm64"
|
||||
# CONTAINER_REGISTRY: "ghcr.io"
|
||||
# CONTAINER_BASE_IMAGE: "docker.io/lancemccarthy/skia-aspnet:10.0"
|
||||
# steps:
|
||||
# - name: Checkout
|
||||
# uses: actions/checkout@v4
|
||||
# with:
|
||||
# fetch-depth: 0
|
||||
|
||||
# - name: Setup .NET Core SDK
|
||||
# uses: actions/setup-dotnet@v4
|
||||
# with:
|
||||
# dotnet-version: ${{env.DOTNET_VERSION}}
|
||||
|
||||
# # Needed because dotnet publish -t:PublishContainer uses the CLI (not docker/login-action@v3)
|
||||
# - name: Login to ghcr.io
|
||||
# run: docker login ${{env.CONTAINER_REGISTRY}} -u ${{github.actor}} -p ${{secrets.GITHUB_TOKEN}}
|
||||
|
||||
# - name: Restore NuGet Packages
|
||||
# run: dotnet restore ${{env.BLAZOR_PROJ_PATH}} -r "linux-${{env.target_arch}}"
|
||||
# env:
|
||||
# TELERIK_USERNAME: "api-key"
|
||||
# TELERIK_PASSWORD: ${{secrets.TELERIK_NUGET_KEY}}
|
||||
|
||||
# - name: build the arm64 image
|
||||
# id: build
|
||||
# run: |
|
||||
# TAG="latest-${{env.target_arch}}"
|
||||
# dotnet publish ${{env.BLAZOR_PROJ_PATH}} \
|
||||
# -t:PublishContainer \
|
||||
# -p PublishProfile=DefaultContainer \
|
||||
# -p ContainerBaseImage=${{env.CONTAINER_BASE_IMAGE}} \
|
||||
# -p ContainerRegistry="${{env.CONTAINER_REGISTRY}}" \
|
||||
# -p ContainerRepository="${{env.CONTAINER_REPOSITORY}}" \
|
||||
# -p ContainerImageTag="$TAG" \
|
||||
# --arch ${{env.target_arch}} \
|
||||
# --no-restore
|
||||
# echo "build_tag=$TAG" >> $GITHUB_OUTPUT
|
||||
# env:
|
||||
# TELERIK_LICENSE: ${{secrets.TELERIK_LICENSE_KEY}}
|
||||
|
||||
# # Create a manifest to combine both images into a single "lancemccarthy/myblazorapp:latest" tag
|
||||
# publish_combined_manifest:
|
||||
# runs-on: ubuntu-latest
|
||||
# name: "[NET SDK] Publish multi-arch manifest"
|
||||
# needs: [build_x64, build_arm64]
|
||||
# env:
|
||||
# CONTAINER_REGISTRY: "ghcr.io"
|
||||
# steps:
|
||||
# - name: Checkout
|
||||
# uses: actions/checkout@v4
|
||||
|
||||
# - name: Login to ghcr.io
|
||||
# run: docker login ${{env.CONTAINER_REGISTRY}} -u ${{github.actor}} -p ${{secrets.GITHUB_TOKEN}}
|
||||
|
||||
# - name: Create multi-arch manifest
|
||||
# run: docker manifest create "${{env.CONTAINER_REPOSITORY}}:latest" "${{env.CONTAINER_REPOSITORY}}:${{needs.build_x64.outputs.build_tag}}" "${{env.CONTAINER_REPOSITORY}}:${{needs.build_arm64.outputs.build_tag}}"
|
||||
|
||||
# - name: Push multi-arch manifest
|
||||
# run: docker manifest push "${{env.CONTAINER_REPOSITORY}}:latest"
|
||||
|
||||
# - name: Delete old images
|
||||
# uses: actions/delete-package-versions@v5
|
||||
# with:
|
||||
# package-name: "myblazorapp"
|
||||
# package-type: container
|
||||
# min-versions-to-keep: 2
|
||||
# token: ${{secrets.GITHUB_TOKEN}}
|
||||
Reference in New Issue
Block a user