Skip to content

Commit

Permalink
Add resuable workflow
Browse files Browse the repository at this point in the history
Add a reusable workflow for the advanced workflow.
  • Loading branch information
martincostello committed Apr 19, 2023
1 parent ceb95e6 commit bc98f0a
Show file tree
Hide file tree
Showing 2 changed files with 239 additions and 19 deletions.
34 changes: 34 additions & 0 deletions .github/workflows/update-dotnet-sdk-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: update-dotnet-sdk-test

on:
workflow_dispatch:

permissions:
contents: read
pull-requests: read

jobs:
update-sdk:
uses: martincostello/update-dotnet-sdk/.github/workflows/update-dotnet-sdk.yml@reusable-workflow
permissions:
contents: write
pull-requests: write
with:
global-json-file: './_global.json'
labels: dependencies
secrets:
repo-token: ${{ secrets.GITHUB_TOKEN }}

print-outputs:
name: Print outcome
needs: update-sdk
if: ${{ needs.update-sdk.outputs.sdk-updated == 'true' }}
runs-on: ubuntu-latest

steps:

- name: Print update details
run: |
echo "PR number: ${{ steps.update.outputs.pull-request-number }}"
echo "PR URL: ${{ steps.update.outputs.pull-request-html-url }}"
echo "SDK version: ${{ steps.update.outputs.sdk-version }}"
224 changes: 205 additions & 19 deletions .github/workflows/update-dotnet-sdk.yml
Original file line number Diff line number Diff line change
@@ -1,37 +1,223 @@
name: update-dotnet-sdk

on:
workflow_dispatch:
workflow_call:
inputs:
branch-name:
description: 'The optional Git branch name to use.'
required: false
type: string
default: ''
channel:
description: 'The optional .NET release channel to download the SDK for (2.1, 3.1, 5.0, etc.).'
required: false
type: string
default: ''
commit-message:
description: 'The optional Git commit message to use.'
required: false
type: string
default: ''
global-json-file:
description: 'The optional path to the global.json file to update.'
required: false
type: string
default: './global.json'
labels:
description: 'The optional comma-separated label(s) to apply to Pull Requests generated by the action.'
required: false
type: string
default: ''
update-nuget-packages:
description: 'If true, the action will update any Microsoft-published NuGet packages to their latest versions for the specified .NET release channel.'
required: false
type: boolean
default: true
include-nuget-packages:
description: 'A comma-separated list of NuGet package IDs (or substrings) to update, if update-nuget-packages is true.'
required: false
type: string
default: 'Microsoft.AspNetCore.,Microsoft.EntityFrameworkCore.,Microsoft.Extensions.,System.Text.Json'
user-email:
description: 'The optional email address to use for the Git commit.'
required: false
type: string
default: 'github-actions[bot]@users.noreply.github.com'
user-name:
description: 'The optional user name to use for the Git commit.'
required: false
type: string
default: 'github-actions[bot]'
dry-run:
description: 'If true, the action will not push changes to GitHub.'
required: false
type: boolean
default: false
runs-on:
description: 'The GitHub Actions runner to use.'
required: false
type: string
default: 'ubuntu-latest'
secrets:
repo-token:
description: 'The GitHub access token to use to clone the repository, push changes and create a Pull Request for any SDK update.'
required: true

permissions:
contents: read
pull-requests: read
env:
TERM: xterm

jobs:
update-sdk:
runs-on: ubuntu-latest

update-dotnet-sdk:

name: Update .NET SDK
runs-on: ${{ inputs.runs-on }}
# We don't want anyone forking this repository to also run this workflow
if: ${{ github.event.repository.fork == false }}

permissions:
contents: write
pull-requests: write
outputs:
pull-request-html-url: ${{ steps.update-dotnet-sdk.outputs.pull-request-html-url }}
pull-request-number: ${{ steps.update-dotnet-sdk.outputs.pull-request-number }}
sdk-updated: ${{ steps.update-dotnet-sdk.outputs.sdk-updated }}
sdk-version: ${{ steps.update-dotnet-sdk.outputs.sdk-version }}

steps:

# Checkout the repository so the global.json file can be inspected and
# updated if a new patch version of the SDK is available. The token is
# used so that the workflow can push any changes back to the repository
# and that pushes as that user trigger any CI workflows that may trigger
# on push, such as if any NuGet packages are updated after the PR is opened.
- name: Checkout code
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
with:
token: ${{ secrets.repo-token }}

# Run the action to check if a new version of the .NET SDK is available
# for the same release channel as the SDK specified in global.json.
- name: Update .NET SDK
id: update
uses: ./
id: update-dotnet-sdk
uses: martincostello/update-dotnet-sdk@8d99db1db36692f0d5c5bf3ef91fb654c2d4e298 # v2.1.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
global-json-file: './_global.json'
labels: dependencies
branch-name: ${{ inputs.branch-name }}
channel: ${{ inputs.channel }}
commit-message: ${{ inputs.commit-message }}
dry-run: ${{ inputs.dry-run }}
global-json-file: ${{ inputs.global-json-file }}
labels: ${{ inputs.labels }}
repo-token: ${{ secrets.repo-token }}
user-email: ${{ inputs.user-email }}
user-name: ${{ inputs.user-name }}

- name: Print outputs
# If the action updated the .NET SDK, then install the .NET SDK and then
# run the dotnet-outdated global tool to update any Microsoft-published
# NuGet packages for that patch release of .NET to their latest versions too.
- name: Setup .NET SDK
uses: actions/setup-dotnet@607fce577a46308457984d59e4954e075820f10a # v3.0.3
if : ${{ inputs.update-nuget-packages && steps.update-dotnet-sdk.outputs.sdk-updated == 'true' }}
with:
global-json-file: ${{ inputs.global-json-file }}

- name: Update NuGet packages
if : ${{ inputs.update-nuget-packages && steps.update-dotnet-sdk.outputs.sdk-updated == 'true' }}
shell: pwsh
env:
DOTNET_CLI_TELEMETRY_OPTOUT: true
DOTNET_NOLOGO: true
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION: 1
NUGET_XMLDOC_MODE: skip
run: |
echo "PR number: ${{ steps.update.outputs.pull-request-number }}"
echo "PR URL: ${{ steps.update.outputs.pull-request-html-url }}"
echo "SDK Updated? ${{ steps.update.outputs.sdk-updated }}"
echo "SDK version: ${{ steps.update.outputs.sdk-version }}"
$ErrorActionPreference = "Stop"
dotnet tool install --global dotnet-outdated-tool
$tempPath = [System.IO.Path]::GetTempPath()
$updatesPath = (Join-Path $tempPath "dotnet-outdated.json")
Write-Host "Checking for .NET NuGet package(s) to update..."
# The --version-lock Major option is used to only update packages
# to the latest patch version of the current major version.
# The --include flags are used to only update Microsoft-published
# NuGet packages that are typically published with a new patch
# release of .NET that accompanies a new .NET SDK release.
$eligblePackages = "${{ inputs.include-nuget-packages }}".Split(',')
$includePackages = $()
foreach ($package in $eligblePackages) {
$includePackages += "--include"
$includePackages += $package
}
dotnet outdated `
--upgrade `
--version-lock Major `
--output $updatesPath `
$includePackages
$dependencies = @()
# Determine the distinct set of package updates that were applied, if any.
if (Test-Path $updatesPath) {
$dependencies = `
Get-Content -Path $updatesPath | `
ConvertFrom-Json | `
Select-Object -ExpandProperty projects | `
Select-Object -ExpandProperty TargetFrameworks | `
Select-Object -ExpandProperty Dependencies | `
Sort-Object -Property Name -Unique
}
if ($dependencies.Count -gt 0) {
Write-Host "Found $($dependencies.Count) .NET NuGet package(s) to update." -ForegroundColor Green
$commitMessageLines = @()
# Generate the commit message in a way that contains metadata similar to the way
# commit messages from dependabot updates are generated so that the approve-and-merge
# workflow can parse the commits to determine which packages were updated so that
# it can determine whether or not it is appropriate to approve the PR and then
# automatically merge it if the required statuses for the pull request are successful.
if ($dependencies.Count -eq 1) {
$commitMessageLines += "Bump $($dependencies[0].Name) from $($dependencies[0].ResolvedVersion) to $($dependencies[0].LatestVersion)"
$commitMessageLines += ""
$commitMessageLines += "Bumps $($dependencies[0].Name) from $($dependencies[0].ResolvedVersion) to $($dependencies[0].LatestVersion)."
} else {
$commitMessageLines += "Bump .NET NuGet packages"
$commitMessageLines += ""
$commitMessageLines += "Bumps .NET dependencies to their latest versions for the .NET ${{ steps.update-dotnet-sdk.outputs.sdk-version }} SDK."
$commitMessageLines += ""
foreach ($dependency in $dependencies) {
$commitMessageLines += "Bumps $($dependency.Name) from $($dependency.ResolvedVersion) to $($dependency.LatestVersion)."
}
}
$commitMessageLines += ""
$commitMessageLines += "---"
$commitMessageLines += "updated-dependencies:"
foreach ($dependency in $dependencies) {
$commitMessageLines += "- dependency-name: $($dependency.Name)"
$commitMessageLines += " dependency-type: direct:production"
$commitMessageLines += " update-type: version-update:semver-$($dependency.UpgradeSeverity.ToLowerInvariant())"
}
$commitMessageLines += "..."
$commitMessageLines += ""
$commitMessageLines += ""
$commitMessage = $commitMessageLines -join "`n"
git config user.email "${{ inputs.user-email }}"
git config user.name "${{ inputs.user-name }}"
git add .
git commit -m $commitMessage
git push
Write-Host "Pushed update to $($dependencies.Count) NuGet package(s)." -ForegroundColor Green
}
else {
Write-Host "There are no .NET NuGet packages to update." -ForegroundColor Green
}

0 comments on commit bc98f0a

Please sign in to comment.