Repository navigation
docs: clarify Front Door regional resiliency and fire-drill gates #97
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Function ZIPs | |
| on: | |
| pull_request: | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: function-zips-${{ github.ref }} | |
| cancel-in-progress: false | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: '22.x' | |
| - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: '3.11' | |
| - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 | |
| with: | |
| dotnet-version: '8.0.x' | |
| - name: Test JavaScript | |
| working-directory: javascript | |
| run: | | |
| npm ci --ignore-scripts --no-audit --no-fund | |
| npm test | |
| - name: Test Python | |
| working-directory: python | |
| run: | | |
| python -m pip install -r requirements.txt pytest | |
| python -m pytest tests | |
| - name: Test .NET | |
| run: dotnet test dotnet/tests/Epp.Otp.Tests.csproj | |
| - name: Build ZIPs | |
| shell: pwsh | |
| run: | | |
| ./package-javascript.ps1 | |
| ./package-dotnet.ps1 | |
| ./package-python.ps1 | |
| - name: Verify existing ZIPs are never overwritten | |
| shell: pwsh | |
| run: | | |
| $packages = @{ | |
| 'package-javascript.ps1' = 'artifacts/epp-javascript.zip' | |
| 'package-dotnet.ps1' = 'artifacts/epp-dotnet-source.zip' | |
| 'package-python.ps1' = 'artifacts/epp-python-source.zip' | |
| } | |
| foreach ($script in ($packages.Keys | Sort-Object)) { | |
| $archive = (Resolve-Path -LiteralPath $packages[$script]).Path | |
| $before = (Get-FileHash -LiteralPath $archive -Algorithm SHA256).Hash | |
| $rejected = $false | |
| try { | |
| & (Join-Path $PWD $script) -OutputPath $archive | |
| } catch { | |
| if (-not $_.Exception.Message.StartsWith('Output already exists:')) { throw } | |
| $rejected = $true | |
| } | |
| if (-not $rejected) { throw "$script did not reject an existing archive" } | |
| if ((Get-FileHash -LiteralPath $archive -Algorithm SHA256).Hash -ne $before) { | |
| throw "$script changed the existing archive" | |
| } | |
| Write-Host "$script rejected the existing output; SHA256 unchanged." | |
| } | |
| - name: Verify ZIPs and write checksums | |
| shell: pwsh | |
| run: | | |
| $required = @{ | |
| 'epp-javascript.zip' = @('host.json', 'src/functions/SendOtp.js', 'node_modules/@azure/functions/package.json') | |
| 'epp-dotnet-source.zip' = @('host.json', 'dotnet.csproj', 'Program.cs', 'Functions/SendOtp.cs', 'Src/PhoneProviderBase.cs') | |
| 'epp-python-source.zip' = @('host.json', 'function_app.py', 'requirements.txt', 'src/jwe.py', 'src/provider.py') | |
| } | |
| $checksums = foreach ($name in ($required.Keys | Sort-Object)) { | |
| $path = Join-Path 'artifacts' $name | |
| $zip = [IO.Compression.ZipFile]::OpenRead((Resolve-Path $path)) | |
| try { | |
| $entries = @($zip.Entries.FullName) | |
| foreach ($file in $required[$name]) { | |
| if ($file -notin $entries) { throw "Missing $file in $name" } | |
| } | |
| if ($entries -match '(^|/)(local\.settings[^/]*|\.env[^/]*|\.git|\.venv|__pycache__)(/|$)|\.(pem|pfx|p12|key|publishsettings|pubxml)$') { | |
| throw "Private files in $name" | |
| } | |
| if ($name -eq 'epp-dotnet-source.zip' -and | |
| ($entries -match '(^|/)(bin|obj|tests?|\.azurefunctions)(/|$)|\.(dll|exe|pdb|deps\.json|runtimeconfig\.json)$|(^|/)(functions\.metadata|worker\.config\.json)$')) { | |
| throw 'Build output or tests found in .NET source ZIP' | |
| } | |
| } finally { $zip.Dispose() } | |
| '{0} {1}' -f (Get-FileHash $path -Algorithm SHA256).Hash.ToLowerInvariant(), $name | |
| } | |
| $checksums | Set-Content artifacts/SHA256SUMS.txt -Encoding utf8 | |
| - name: Verify .NET source ZIP can be published by customers | |
| shell: pwsh | |
| run: | | |
| $temporary = Join-Path ([IO.Path]::GetTempPath()) ('epp-source-check-' + [guid]::NewGuid().ToString('N')) | |
| try { | |
| $source = Join-Path $temporary 'source' | |
| $publish = Join-Path $temporary 'publish' | |
| [IO.Compression.ZipFile]::ExtractToDirectory((Resolve-Path 'artifacts/epp-dotnet-source.zip'), $source) | |
| dotnet publish (Join-Path $source 'dotnet.csproj') --configuration Release --output $publish --verbosity minimal | |
| if ($LASTEXITCODE -ne 0) { throw 'Extracted .NET source could not be published' } | |
| foreach ($file in @('host.json', 'dotnet.dll', 'functions.metadata', 'worker.config.json', '.azurefunctions')) { | |
| if (-not (Test-Path -LiteralPath (Join-Path $publish $file))) { throw "Missing customer publish output: $file" } | |
| } | |
| } finally { | |
| if (Test-Path -LiteralPath $temporary) { Remove-Item -LiteralPath $temporary -Recurse -Force } | |
| } | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: function-zips | |
| path: | | |
| artifacts/epp-javascript.zip | |
| artifacts/epp-dotnet-source.zip | |
| artifacts/epp-python-source.zip | |
| artifacts/SHA256SUMS.txt | |
| if-no-files-found: error | |
| retention-days: 14 | |
| publish: | |
| if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' | |
| needs: build | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: function-zips | |
| path: artifacts | |
| - name: Publish versioned ZIP downloads | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| GH_REPO: ${{ github.repository }} | |
| COMMIT_SHA: ${{ github.sha }} | |
| RUN_NUMBER: ${{ github.run_number }} | |
| RUN_ATTEMPT: ${{ github.run_attempt }} | |
| run: | | |
| tag="epp-packages-${RUN_NUMBER}-${RUN_ATTEMPT}" | |
| gh release create "$tag" artifacts/*.zip artifacts/SHA256SUMS.txt \ | |
| --target "$COMMIT_SHA" --title "EPP Function ZIPs ${RUN_NUMBER}.${RUN_ATTEMPT}" \ | |
| --latest \ | |
| --notes "Packaged and tested from commit ${COMMIT_SHA}. Download one language ZIP and verify it against SHA256SUMS.txt. JavaScript includes production dependencies. .NET contains project and C# source only: extract and build/publish the project before deployment. Python is a source ZIP requiring Azure remote build on Linux. Neither source ZIP is a direct run-from-package artifact. Configure runtime, app settings, Key Vault access, and Easy Auth separately. No cloud deployment or live provider verification is performed." |