diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fe9f46a..c7aa55a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,5 @@ -name: BuildTestDeploy +name: BuildAndTest + on: workflow_dispatch: push: @@ -6,9 +7,6 @@ on: - main - 'release/*' pull_request: - release: - types: - - published schedule: # Run this workflow at 6 PM UTC every Sunday - cron: "0 18 * * 0" @@ -26,8 +24,8 @@ env: VERSION_FILE: 'src/Steeltoe.NetCoreTool.Templates.csproj' jobs: - build-and-test: - name: Build, Test and Package + build: + name: Build and Test timeout-minutes: 60 strategy: fail-fast: false @@ -52,260 +50,8 @@ jobs: - name: Restore packages run: dotnet restore --verbosity minimal - - name: Calculate package version (for release) - if: ${{ github.event_name == 'release' }} - env: - TAG_NAME: ${{ github.ref_name }} - shell: pwsh - run: | - # Get the version suffix from the git tag. For example: '1.2.3-preview1-final' => 'preview1-final' - $tagSegments = '${{ env.TAG_NAME }}' -split '-' - $versionPrefix = $tagSegments[0] - $versionSuffix = $tagSegments.Length -eq 1 ? '' : $tagSegments[1..$($tagSegments.Length - 1)] -join '-' - - [xml]$xml = Get-Content $env:VERSION_FILE - $configuredVersionPrefix = $xml.Project.PropertyGroup.VersionPrefix | Select-Object -First 1 - - if ($configuredVersionPrefix -ne $versionPrefix) { - Write-Error "Version prefix from git release tag '$versionPrefix' does not match version prefix '$configuredVersionPrefix' stored in $env:VERSION_FILE." - # To recover from this: - # - Delete the GitHub release - # - Run: git push --delete origin the-invalid-tag-name - # - Adjust VersionPrefix in file, commit and push - # - Recreate the GitHub release - } - - Write-Output "Using version suffix: $versionSuffix" - Write-Output "PACKAGE_VERSION_SUFFIX=$versionSuffix" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - - - name: Calculate package version (for branch) - if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' }} - env: - BRANCH_NAME: ${{ github.ref_name }} - shell: pwsh - run: | - # Get the version suffix from the branch name and auto-incrementing build number. For example: 'main' and '123' => 'main-00123' - $revision = "{0:D5}" -f ${{ github.run_number }} - $branchName = '${{ env.BRANCH_NAME }}' - $safeBranchName = $branchName -Replace '[^a-zA-Z0-9-]', '-' - $versionSuffix = "$safeBranchName-$revision" - - Write-Output "Using version suffix: $versionSuffix" - Write-Output "PACKAGE_VERSION_SUFFIX=$versionSuffix" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - - - name: Calculate package version (for pr) - if: ${{ github.event_name == 'pull_request' }} - shell: pwsh - run: | - # Get the version suffix from the PR number and auto-incrementing build number. For example: '18' and '123' => 'pr18-00123' - $revision = "{0:D5}" -f ${{ github.run_number }} - $versionSuffix = "pr${{ github.event.number }}-$revision" - - Write-Output "Using version suffix: $versionSuffix" - Write-Output "PACKAGE_VERSION_SUFFIX=$versionSuffix" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - - - name: Verify package version - if: ${{ !env.PACKAGE_VERSION_SUFFIX && github.event_name != 'release' }} - run: | - echo "Package version suffix is empty. This should never happen." - exit 1 - - name: Build solution - run: dotnet build --no-restore --configuration Release --verbosity minimal /p:VersionSuffix=${{ env.PACKAGE_VERSION_SUFFIX }} + run: dotnet build --no-restore --configuration Release --verbosity minimal - name: Test run: dotnet test --no-build --configuration Release --collect:"XPlat Code Coverage" --logger "GitHubActions;summary.includeSkippedTests=true" - - - name: Collect packages - run: dotnet pack src --no-build --configuration Release --output ${{ github.workspace }}/packages /p:VersionSuffix=${{ env.PACKAGE_VERSION_SUFFIX }} - - - name: Upload unsigned packages - if: ${{ matrix.os == 'ubuntu-latest' }} - uses: actions/upload-artifact@v7 - with: - if-no-files-found: error - name: unsigned-packages - path: ${{ github.workspace }}/packages/**/*.nupkg - - sign: - name: Sign - if: ${{ github.event_name != 'pull_request' }} - timeout-minutes: 15 - needs: build-and-test - runs-on: windows-latest - environment: signing - permissions: - id-token: write - - steps: - - name: Download unsigned packages - uses: actions/download-artifact@v8 - with: - name: unsigned-packages - path: packages - - - name: Setup .NET - uses: actions/setup-dotnet@v5 - with: - dotnet-version: 10.0.* - - - name: Install code signing tool - run: dotnet tool install --global sign --prerelease - - - name: Azure login - uses: azure/login@v3 - with: - client-id: ${{ secrets.AZURE_CLIENT_ID }} - tenant-id: ${{ secrets.AZURE_TENANT_ID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - - - name: Sign packages - run: >- - sign code azure-key-vault '**/*.nupkg' - --base-directory '${{ github.workspace }}/packages' - --azure-key-vault-managed-identity true - --azure-credential-type 'azure-cli' - --azure-key-vault-url '${{ secrets.AZURE_KEY_VAULT_URL }}' - --azure-key-vault-certificate '${{ secrets.AZURE_SIGN_CERTIFICATE_ID }}' - --publisher-name 'Steeltoe' - --description 'Steeltoe' - --description-url 'https://steeltoe.io/' - - - name: Upload signed packages - uses: actions/upload-artifact@v7 - with: - if-no-files-found: error - name: signed-packages - path: ${{ github.workspace }}/packages/**/*.nupkg - - dev-feed-deploy: - name: Deploy packages to development feed - timeout-minutes: 15 - needs: sign - if: ${{ github.event_name != 'pull_request' && github.event_name != 'schedule' }} - environment: azdo - runs-on: ubuntu-latest - permissions: - id-token: write - env: - VSS_NUGET_URI_PREFIXES: https://pkgs.dev.azure.com/dotnet/ - - steps: - - name: Azure login - uses: azure/login@v3 - with: - client-id: ${{ secrets.AZURE_CLIENT_ID }} - tenant-id: ${{ secrets.AZURE_TENANT_ID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - - - name: Download signed packages - uses: actions/download-artifact@v8 - with: - name: signed-packages - path: packages - - - name: Setup .NET - uses: actions/setup-dotnet@v5 - with: - dotnet-version: 10.0.x - source-url: ${{ vars.AZURE_ARTIFACTS_FEED_URL }} - env: - NUGET_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Install credential provider for Azure Artifacts - run: sh -c "$(curl -fsSL https://aka.ms/install-artifacts-credprovider.sh)" - - - name: Extract access token - run: | - accessToken=$(az account get-access-token --query accessToken --resource 499b84ac-1321-427f-aa17-267ca6975798 -o tsv) - echo "::add-mask::$accessToken" - echo "ACCESS_TOKEN=$accessToken" >> $GITHUB_ENV - - - name: Configure authentication provider to use Azure DevOps token - run: echo "VSS_NUGET_ACCESSTOKEN=$ACCESS_TOKEN" >> $GITHUB_ENV - - - name: Push packages to Azure Artifacts - run: dotnet nuget push '${{ github.workspace }}/packages/*.nupkg' --api-key 'azdo-placeholder' --source '${{ vars.AZURE_ARTIFACTS_FEED_URL }}' - - nuget-org-deploy: - name: Deploy packages to nuget.org - needs: sign - if: ${{ github.event_name == 'release' }} - environment: nuget.org - runs-on: ubuntu-latest - permissions: - id-token: write - - steps: - - name: Setup .NET - uses: actions/setup-dotnet@v5 - with: - dotnet-version: 10.0.x - - - name: Download signed packages - uses: actions/download-artifact@v8 - with: - name: signed-packages - path: packages - - - name: NuGet login - uses: NuGet/login@v1 - id: nuget-login - with: - user: ${{ secrets.NUGET_USER }} - - - name: Push packages to nuget.org - run: dotnet nuget push '${{ github.workspace }}/packages/*.nupkg' --skip-duplicate --api-key '${{ steps.nuget-login.outputs.NUGET_API_KEY }}' --source 'nuget.org' - - open_pr: - name: Open pull request to bump templates version after stable release - if: ${{ github.event_name == 'release' && !contains(github.ref_name, '-') }} - needs: nuget-org-deploy - timeout-minutes: 15 - runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - - steps: - - name: Git checkout - uses: actions/checkout@v6 - - - name: Calculate next package version - shell: pwsh - run: | - [xml]$xml = Get-Content $env:VERSION_FILE - $oldVersionPrefix = $xml.Project.PropertyGroup.VersionPrefix | Select-Object -First 1 - - $versionSegments = $oldVersionPrefix.split('.') - ([int]$versionSegments[-1])++ - $newVersionPrefix = $versionSegments -join('.') - - Write-Output "OLD_PACKAGE_VERSION_PREFIX=$oldVersionPrefix" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - Write-Output "NEW_PACKAGE_VERSION_PREFIX=$newVersionPrefix" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - - - name: Open pull request - env: - GH_TOKEN: ${{ github.token }} - shell: pwsh - run: | - $oldVersionPrefix = '${{ env.OLD_PACKAGE_VERSION_PREFIX }}' - $newVersionPrefix = '${{ env.NEW_PACKAGE_VERSION_PREFIX }}' - $prBranchName = "bump-version-to-$newVersionPrefix-${{ github.run_number }}" - $commitMessage = "Bump templates version from $oldVersionPrefix to $newVersionPrefix.`n`n> [!TIP]`n> Close and reopen this pull request to run status checks." - - $pattern = '(?^\s*\)[^>]+(?\<\/VersionPrefix\>)\s*$' - $fileContent = Get-Content $env:VERSION_FILE - $fileContent = $fileContent -Replace $pattern,"`${left}$newVersionPrefix`${right}" - Set-Content $fileContent -Path $env:VERSION_FILE - - Write-Output "Creating pull request with commit message:`n$commitMessage" - git config --local user.name "github-actions[bot]" - git config --local user.email "github-actions[bot]@users.noreply.github.com" - git checkout -b $prBranchName - git add -A - git commit -m $commitMessage - git push --set-upstream origin $prBranchName - - Write-Output "Opening pull request to merge $prBranchName." - gh pr create --head $prBranchName --title 'Bump templates version' --body $commitMessage diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml new file mode 100644 index 0000000..9186e7c --- /dev/null +++ b/.github/workflows/package.yml @@ -0,0 +1,303 @@ +name: Package + +on: + workflow_dispatch: + push: + branches: + - main + - 'release/*' + pull_request: + release: + types: + - published + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +env: + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_NOLOGO: true + VERSION_FILE: 'src/Steeltoe.NetCoreTool.Templates.csproj' + +jobs: + build: + name: Build and Package + timeout-minutes: 15 + runs-on: ubuntu-latest + + steps: + - name: Setup .NET + uses: actions/setup-dotnet@v5 + with: + dotnet-version: | + 8.0.* + 9.0.* + 10.0.* + + - name: Git checkout + uses: actions/checkout@v6 + with: + persist-credentials: false + + - name: Restore packages + run: dotnet restore --verbosity minimal + + - name: Calculate package version (for release) + if: ${{ github.event_name == 'release' }} + env: + TAG_NAME: ${{ github.ref_name }} + shell: pwsh + run: | + # Get the version suffix from the git tag. For example: '1.2.3-preview1-final' => 'preview1-final' + $tagSegments = '${{ env.TAG_NAME }}' -split '-' + $versionPrefix = $tagSegments[0] + $versionSuffix = $tagSegments.Length -eq 1 ? '' : $tagSegments[1..$($tagSegments.Length - 1)] -join '-' + + [xml]$xml = Get-Content $env:VERSION_FILE + $configuredVersionPrefix = $xml.Project.PropertyGroup.VersionPrefix | Select-Object -First 1 + + if ($configuredVersionPrefix -ne $versionPrefix) { + Write-Error "Version prefix from git release tag '$versionPrefix' does not match version prefix '$configuredVersionPrefix' stored in $env:VERSION_FILE." + # To recover from this: + # - Delete the GitHub release + # - Run: git push --delete origin the-invalid-tag-name + # - Adjust VersionPrefix in file, commit and push + # - Recreate the GitHub release + } + + Write-Output "Using version suffix: $versionSuffix" + Write-Output "PACKAGE_VERSION_SUFFIX=$versionSuffix" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + + - name: Calculate package version (for branch) + if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }} + env: + BRANCH_NAME: ${{ github.ref_name }} + shell: pwsh + run: | + # Get the version suffix from the branch name and auto-incrementing build number. For example: 'main' and '123' => 'main-00123' + $revision = "{0:D5}" -f ${{ github.run_number }} + $branchName = '${{ env.BRANCH_NAME }}' + $safeBranchName = $branchName -Replace '[^a-zA-Z0-9-]', '-' + $versionSuffix = "$safeBranchName-$revision" + + Write-Output "Using version suffix: $versionSuffix" + Write-Output "PACKAGE_VERSION_SUFFIX=$versionSuffix" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + + - name: Calculate package version (for pr) + if: ${{ github.event_name == 'pull_request' }} + shell: pwsh + run: | + # Get the version suffix from the PR number and auto-incrementing build number. For example: '18' and '123' => 'pr18-00123' + $revision = "{0:D5}" -f ${{ github.run_number }} + $versionSuffix = "pr${{ github.event.number }}-$revision" + + Write-Output "Using version suffix: $versionSuffix" + Write-Output "PACKAGE_VERSION_SUFFIX=$versionSuffix" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + + - name: Verify package version + if: ${{ !env.PACKAGE_VERSION_SUFFIX && github.event_name != 'release' }} + run: | + echo "Package version suffix is empty. This should never happen." + exit 1 + + - name: Build solution + run: dotnet build --no-restore --configuration Release --verbosity minimal /p:VersionSuffix=${{ env.PACKAGE_VERSION_SUFFIX }} + + - name: Collect packages + run: dotnet pack src --no-build --configuration Release --output ${{ github.workspace }}/packages /p:VersionSuffix=${{ env.PACKAGE_VERSION_SUFFIX }} + + - name: Upload unsigned packages + uses: actions/upload-artifact@v7 + with: + if-no-files-found: error + name: unsigned-packages + path: ${{ github.workspace }}/packages/**/*.nupkg + + sign: + name: Sign + if: ${{ github.event_name != 'pull_request' }} + timeout-minutes: 15 + needs: build + runs-on: windows-latest + environment: signing + permissions: + id-token: write + + steps: + - name: Download unsigned packages + uses: actions/download-artifact@v8 + with: + name: unsigned-packages + path: packages + + - name: Setup .NET + uses: actions/setup-dotnet@v5 + with: + dotnet-version: 10.0.* + + - name: Install code signing tool + run: dotnet tool install --global sign --prerelease + + - name: Azure login + uses: azure/login@v3 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + + - name: Sign packages + run: >- + sign code azure-key-vault '**/*.nupkg' + --base-directory '${{ github.workspace }}/packages' + --azure-key-vault-managed-identity true + --azure-credential-type 'azure-cli' + --azure-key-vault-url '${{ secrets.AZURE_KEY_VAULT_URL }}' + --azure-key-vault-certificate '${{ secrets.AZURE_SIGN_CERTIFICATE_ID }}' + --publisher-name 'Steeltoe' + --description 'Steeltoe' + --description-url 'https://steeltoe.io/' + + - name: Upload signed packages + uses: actions/upload-artifact@v7 + with: + if-no-files-found: error + name: signed-packages + path: ${{ github.workspace }}/packages/**/*.nupkg + + dev-feed-deploy: + name: Deploy packages to development feed + timeout-minutes: 15 + needs: sign + if: ${{ github.event_name != 'pull_request' }} + environment: azdo + runs-on: ubuntu-latest + permissions: + id-token: write + env: + VSS_NUGET_URI_PREFIXES: https://pkgs.dev.azure.com/dotnet/ + + steps: + - name: Azure login + uses: azure/login@v3 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + + - name: Download signed packages + uses: actions/download-artifact@v8 + with: + name: signed-packages + path: packages + + - name: Setup .NET + uses: actions/setup-dotnet@v5 + with: + dotnet-version: 10.0.* + source-url: ${{ vars.AZURE_ARTIFACTS_FEED_URL }} + env: + NUGET_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Install credential provider for Azure Artifacts + run: sh -c "$(curl -fsSL https://aka.ms/install-artifacts-credprovider.sh)" + + - name: Extract access token + run: | + accessToken=$(az account get-access-token --query accessToken --resource 499b84ac-1321-427f-aa17-267ca6975798 -o tsv) + echo "::add-mask::$accessToken" + echo "ACCESS_TOKEN=$accessToken" >> $GITHUB_ENV + + - name: Configure authentication provider to use Azure DevOps token + run: echo "VSS_NUGET_ACCESSTOKEN=$ACCESS_TOKEN" >> $GITHUB_ENV + + - name: Push packages to Azure Artifacts + run: dotnet nuget push '${{ github.workspace }}/packages/*.nupkg' --api-key 'azdo-placeholder' --source '${{ vars.AZURE_ARTIFACTS_FEED_URL }}' + + nuget-org-deploy: + name: Deploy packages to nuget.org + needs: sign + if: ${{ github.event_name == 'release' }} + environment: nuget.org + runs-on: ubuntu-latest + permissions: + id-token: write + + steps: + - name: Setup .NET + uses: actions/setup-dotnet@v5 + with: + dotnet-version: 10.0.* + + - name: Download signed packages + uses: actions/download-artifact@v8 + with: + name: signed-packages + path: packages + + - name: NuGet login + uses: NuGet/login@v1 + id: nuget-login + with: + user: ${{ secrets.NUGET_USER }} + + - name: Push packages to nuget.org + run: dotnet nuget push '${{ github.workspace }}/packages/*.nupkg' --skip-duplicate --api-key '${{ steps.nuget-login.outputs.NUGET_API_KEY }}' --source 'nuget.org' + + open_pr: + name: Open pull request to bump templates version after stable release + if: ${{ github.event_name == 'release' && !contains(github.ref_name, '-') }} + needs: nuget-org-deploy + timeout-minutes: 15 + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + + steps: + - name: Git checkout + uses: actions/checkout@v6 + with: + persist-credentials: true + + - name: Calculate next package version + shell: pwsh + run: | + [xml]$xml = Get-Content $env:VERSION_FILE + $oldVersionPrefix = $xml.Project.PropertyGroup.VersionPrefix | Select-Object -First 1 + + $versionSegments = $oldVersionPrefix.split('.') + ([int]$versionSegments[-1])++ + $newVersionPrefix = $versionSegments -join('.') + + Write-Output "OLD_PACKAGE_VERSION_PREFIX=$oldVersionPrefix" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + Write-Output "NEW_PACKAGE_VERSION_PREFIX=$newVersionPrefix" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + + - name: Open pull request + env: + GH_TOKEN: ${{ github.token }} + shell: pwsh + run: | + $oldVersionPrefix = '${{ env.OLD_PACKAGE_VERSION_PREFIX }}' + $newVersionPrefix = '${{ env.NEW_PACKAGE_VERSION_PREFIX }}' + $prBranchName = "bump-version-to-$newVersionPrefix-${{ github.run_number }}" + $commitMessage = "Bump templates version from $oldVersionPrefix to $newVersionPrefix.`n`n> [!TIP]`n> Close and reopen this pull request to run status checks." + + $pattern = '(?^\s*\)[^>]+(?\<\/VersionPrefix\>)\s*$' + $fileContent = Get-Content $env:VERSION_FILE + $fileContent = $fileContent -Replace $pattern,"`${left}$newVersionPrefix`${right}" + Set-Content $fileContent -Path $env:VERSION_FILE + + Write-Output "Creating pull request with commit message:`n$commitMessage" + git config --local user.name "github-actions[bot]" + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git checkout -b $prBranchName + git add -A + git commit -m $commitMessage + git push --set-upstream origin $prBranchName + + Write-Output "Opening pull request to merge $prBranchName." + gh pr create --head $prBranchName --title 'Bump templates version from $oldVersionPrefix to $newVersionPrefix' --body $commitMessage