Skip to content

Consume .NET nightly builds #4218

Consume .NET nightly builds

Consume .NET nightly builds #4218

Workflow file for this run

name: build
on:
push:
branches: [ main ]
paths-ignore:
- '**/*.gitattributes'
- '**/*.gitignore'
- '**/*.md'
pull_request:
branches:
- main
- dotnet-vnext
- dotnet-nightly
workflow_dispatch:
env:
APPLICATION_URL_DEV: https://londontravel-dev.martincostello.com
APPLICATION_URL_PROD: https://londontravel.martincostello.com
AZURE_WEBAPP_NAME: londontravel-martincostello
CONTAINER_REGISTRY: '${{ github.repository_owner }}.azurecr.io'
DOTNET_CLI_TELEMETRY_OPTOUT: true
DOTNET_GENERATE_ASPNET_CERTIFICATE: false
DOTNET_MULTILEVEL_LOOKUP: 0
DOTNET_NOLOGO: true
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION: 1
FORCE_COLOR: 1
NUGET_XMLDOC_MODE: skip
TERM: xterm
permissions:
contents: read
jobs:
build:
name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
env:
PUBLISH_CONTAINER: ${{ github.event.repository.fork == false && ((github.ref_name == github.event.repository.default_branch) || (github.actor == github.repository_owner)) && matrix.os == 'ubuntu-latest' }}
outputs:
container-tag: ${{ steps.publish-container.outputs.container-tag }}
permissions:
attestations: write
contents: read
id-token: write
strategy:
fail-fast: false
matrix:
include:
- os: macos-latest
os-name: macos
- os: ubuntu-latest
os-name: linux
- os: windows-latest
os-name: windows
steps:
- name: Checkout code
uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Setup .NET SDK
uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3 # v4.0.0
- name: Setup Node
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: '20'
- name: Get npm cache directory
id: npm-cache-dir
shell: pwsh
run: echo "dir=$(npm config get cache)" >> ${env:GITHUB_OUTPUT}
- name: Setup npm cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
id: npm-cache
with:
path: ${{ steps.npm-cache-dir.outputs.dir }}
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: ${{ runner.os }}-node-
- name: Setup NuGet cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/*.props') }}
restore-keys: ${{ runner.os }}-nuget-
- name: Setup Playwright cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with:
key: ${{ runner.os }}-playwright-${{ hashFiles('Directory.Packages.props') }}
path: |
~/AppData/Local/ms-playwright
~/.cache/ms-playwright
~/Library/Caches/ms-playwright
- name: Install .NET Workloads
shell: pwsh
run: dotnet workload restore --skip-manifest-update --skip-sign-check
- name: Build, test and publish
shell: pwsh
run: ./build.ps1
- uses: codecov/codecov-action@5ecb98a3c6b747ed38dc09f787459979aebb39be # v4.3.1
name: Upload coverage to Codecov
with:
file: ./artifacts/coverage/coverage.cobertura.xml
flags: ${{ matrix.os-name }}
token: ${{ secrets.CODECOV_TOKEN }}
- name: Docker log in
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
if: env.PUBLISH_CONTAINER == 'true'
with:
registry: ${{ env.CONTAINER_REGISTRY }}
username: ${{ secrets.ACR_REGISTRY_USERNAME }}
password: ${{ secrets.ACR_REGISTRY_PASSWORD }}
- name: Publish container
id: publish-container
if: runner.os == 'Linux'
shell: pwsh
env:
ContainerRegistry: ${{ env.PUBLISH_CONTAINER == 'true' && env.CONTAINER_REGISTRY || '' }}
run: |
dotnet publish ./src/LondonTravel.Site --arch x64 --os linux -p:PublishProfile=DefaultContainer
- name: Attest container image
uses: actions/attest-build-provenance@951c0c5f8e375ad4efad33405ab77f7ded2358e4 # v1.1.1
if: steps.publish-container.outputs.container-digest != ''
with:
push-to-registry: true
subject-digest: ${{ steps.publish-container.outputs.container-digest }}
subject-name: ${{ steps.publish-container.outputs.container-image }}
- name: Publish screenshots
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
if: ${{ !cancelled() }}
with:
name: screenshots-${{ matrix.os-name }}
path: ./artifacts/screenshots/*
if-no-files-found: ignore
- name: Publish traces
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
if: ${{ !cancelled() }}
with:
name: traces-${{ matrix.os-name }}
path: ./artifacts/traces/*
if-no-files-found: ignore
- name: Publish videos
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
if: ${{ !cancelled() }}
with:
name: videos-${{ matrix.os-name }}
path: ./artifacts/videos/*
if-no-files-found: ignore
deploy-dev:
if: github.event.repository.fork == false && github.ref_name == github.event.repository.default_branch
name: dev
needs: build
runs-on: ubuntu-latest
concurrency: development_environment
environment:
name: dev
url: ${{ env.APPLICATION_URL_DEV }}
permissions:
id-token: write
steps:
- name: Azure log in
uses: azure/login@6b2456866fc08b011acb422a92a4aa20e2c4de32 # v2.1.0
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Deploy container to Azure App Service
uses: azure/webapps-deploy@de617f46172a906d0617bb0e50d81e9e3aec24c8 # v3.0.1
with:
app-name: ${{ env.AZURE_WEBAPP_NAME }}
images: ${{ needs.build.outputs.container-tag }}
slot-name: dev
- name: Check application health
shell: pwsh
env:
APPLICATION_URL: ${{ env.APPLICATION_URL_DEV }}
run: |
$delay = 10
$limit = 15
$success = $false
for ($i = 0; $i -lt $limit; $i++) {
$response = $null
try {
$response = Invoke-WebRequest -Uri "${env:APPLICATION_URL}/version" -Method Get -UseBasicParsing
} catch {
$response = $_.Exception.Response
}
if (($null -ne $response) -And ($response.StatusCode -eq 200)) {
$json = $response.Content | ConvertFrom-Json
$version = $json.applicationVersion
if ((-Not [string]::IsNullOrWhiteSpace($version)) -And $version.Contains(${env:GITHUB_SHA})) {
$success = $true
break
}
}
Start-Sleep -Seconds $delay
}
if (-Not $success) {
throw "${env:APPLICATION_URL} did not return a successful status code and the expected version within the time limit after $limit attempts."
}
test-dev:
name: test-dev
needs: deploy-dev
runs-on: ubuntu-latest
concurrency: development_environment
steps:
- name: Checkout code
uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Setup .NET SDK
uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3 # v4.0.0
- name: Setup NuGet cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/*.props') }}
restore-keys: ${{ runner.os }}-nuget-
- name: Setup Playwright cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with:
key: ${{ runner.os }}-playwright-${{ hashFiles('Directory.Packages.props') }}
path: |
~/AppData/Local/ms-playwright
~/.cache/ms-playwright
~/Library/Caches/ms-playwright
- name: Run end-to-end tests
shell: pwsh
run: dotnet test ./tests/LondonTravel.Site.Tests --configuration Release --filter Category=EndToEnd --logger "GitHubActions;report-warnings=false"
env:
WEBSITE_URL: ${{ env.APPLICATION_URL_DEV }}
WEBSITE_USER_GOOGLE_USERNAME: ${{ secrets.WEBSITE_USER_GOOGLE_USERNAME }}
WEBSITE_USER_GOOGLE_PASSWORD: ${{ secrets.WEBSITE_USER_GOOGLE_PASSWORD }}
WEBSITE_USER_MICROSOFT_USERNAME: ${{ secrets.WEBSITE_USER_MICROSOFT_USERNAME }}
WEBSITE_USER_MICROSOFT_PASSWORD: ${{ secrets.WEBSITE_USER_MICROSOFT_PASSWORD }}
WEBSITE_USER_TWITTER_USERNAME: ${{ secrets.WEBSITE_USER_TWITTER_USERNAME }}
WEBSITE_USER_TWITTER_PASSWORD: ${{ secrets.WEBSITE_USER_TWITTER_PASSWORD }}
- name: Publish screenshots
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
if: ${{ !cancelled() }}
with:
name: screenshots-e2e-dev
path: ./artifacts/screenshots/*
if-no-files-found: ignore
- name: Publish traces
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
if: ${{ !cancelled() }}
with:
name: traces-e2e-dev
path: ./artifacts/traces/*
if-no-files-found: ignore
- name: Publish videos
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
if: ${{ !cancelled() }}
with:
name: videos-e2e-dev
path: ./artifacts/videos/*
if-no-files-found: ignore
deploy-prod:
name: production
needs: [ build, test-dev ]
runs-on: ubuntu-latest
concurrency: production_environment
environment:
name: production
url: ${{ env.APPLICATION_URL_PROD }}
permissions:
id-token: write
steps:
- name: Azure log in
uses: azure/login@6b2456866fc08b011acb422a92a4aa20e2c4de32 # v2.1.0
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Deploy container to Azure App Service
uses: azure/webapps-deploy@de617f46172a906d0617bb0e50d81e9e3aec24c8 # v3.0.1
with:
app-name: ${{ env.AZURE_WEBAPP_NAME }}
images: ${{ needs.build.outputs.container-tag }}
- name: Check application health
shell: pwsh
env:
APPLICATION_URL: ${{ env.APPLICATION_URL_PROD }}
run: |
$delay = 10
$limit = 15
$success = $false
for ($i = 0; $i -lt $limit; $i++) {
$response = $null
try {
$response = Invoke-WebRequest -Uri "${env:APPLICATION_URL}/version" -Method Get -UseBasicParsing
} catch {
$response = $_.Exception.Response
}
if (($null -ne $response) -And ($response.StatusCode -eq 200)) {
$json = $response.Content | ConvertFrom-Json
$version = $json.applicationVersion
if ((-Not [string]::IsNullOrWhiteSpace($version)) -And $version.Contains(${env:GITHUB_SHA})) {
$success = $true
break
}
}
Start-Sleep -Seconds $delay
}
if (-Not $success) {
throw "${env:APPLICATION_URL} did not return a successful status code and the expected version within the time limit after $limit attempts."
}
test-prod:
name: test-prod
needs: deploy-prod
runs-on: ubuntu-latest
concurrency: production_environment
steps:
- name: Checkout code
uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Setup .NET SDK
uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3 # v4.0.0
- name: Setup NuGet cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/*.props') }}
restore-keys: ${{ runner.os }}-nuget-
- name: Setup Playwright cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with:
key: ${{ runner.os }}-playwright-${{ hashFiles('Directory.Packages.props') }}
path: |
~/AppData/Local/ms-playwright
~/.cache/ms-playwright
~/Library/Caches/ms-playwright
- name: Run end-to-end tests
shell: pwsh
run: dotnet test ./tests/LondonTravel.Site.Tests --configuration Release --filter Category=EndToEnd --logger "GitHubActions;report-warnings=false"
env:
WEBSITE_URL: ${{ env.APPLICATION_URL_PROD }}
WEBSITE_USER_GOOGLE_USERNAME: ${{ secrets.WEBSITE_USER_GOOGLE_USERNAME }}
WEBSITE_USER_GOOGLE_PASSWORD: ${{ secrets.WEBSITE_USER_GOOGLE_PASSWORD }}
WEBSITE_USER_MICROSOFT_USERNAME: ${{ secrets.WEBSITE_USER_MICROSOFT_USERNAME }}
WEBSITE_USER_MICROSOFT_PASSWORD: ${{ secrets.WEBSITE_USER_MICROSOFT_PASSWORD }}
WEBSITE_USER_TWITTER_USERNAME: ${{ secrets.WEBSITE_USER_TWITTER_USERNAME }}
WEBSITE_USER_TWITTER_PASSWORD: ${{ secrets.WEBSITE_USER_TWITTER_PASSWORD }}
- name: Publish screenshots
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
if: ${{ !cancelled() }}
with:
name: screenshots-e2e-production
path: ./artifacts/screenshots/*
if-no-files-found: ignore
- name: Publish traces
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
if: ${{ !cancelled() }}
with:
name: traces-e2e-production
path: ./artifacts/traces/*
if-no-files-found: ignore
- name: Publish videos
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
if: ${{ !cancelled() }}
with:
name: videos-e2e-production
path: ./artifacts/videos/*
if-no-files-found: ignore