Skip to content

Commit fd9dd57

Browse files
Expose projects to upgrade (#92)
* Upgrade packages. Output two new values. Update README.md and action.yml. Modernize. * Apply suggestions from code review Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> --------- Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com>
1 parent 5b5aefb commit fd9dd57

26 files changed

+415
-211
lines changed

README.md

Lines changed: 100 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
# 🎯 LTS (or current) versions
2-
## .NET version sweeper
1+
# 🎯 LTS (or STS) versions
2+
## .NET version sweeper
33

44
[![build & test](https://github.com/dotnet/versionsweeper/actions/workflows/build-and-test.yml/badge.svg)](https://github.com/dotnet/versionsweeper/actions/workflows/build-and-test.yml)
55
[![target supported version](https://github.com/dotnet/versionsweeper/actions/workflows/dog-food.yml/badge.svg)](https://github.com/dotnet/versionsweeper/actions/workflows/dog-food.yml)
66
[![code-ql analysis](https://github.com/dotnet/versionsweeper/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/dotnet/versionsweeper/actions/workflows/codeql-analysis.yml)
7-
[![GitHub Marketplace](https://img.shields.io/badge/marketplace-.NET%20version%20sweeper-green?colorA=24292e&colorB=97ca00&style=flat&longCache=true&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAM6wAADOsB5dZE0gAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAERSURBVCiRhZG/SsMxFEZPfsVJ61jbxaF0cRQRcRJ9hlYn30IHN/+9iquDCOIsblIrOjqKgy5aKoJQj4O3EEtbPwhJbr6Te28CmdSKeqzeqr0YbfVIrTBKakvtOl5dtTkK+v4HfA9PEyBFCY9AGVgCBLaBp1jPAyfAJ/AAdIEG0dNAiyP7+K1qIfMdonZic6+WJoBJvQlvuwDqcXadUuqPA1NKAlexbRTAIMvMOCjTbMwl1LtI/6KWJ5Q6rT6Ht1MA58AX8Apcqqt5r2qhrgAXQC3CZ6i1+KMd9TRu3MvA3aH/fFPnBodb6oe6HM8+lYHrGdRXW8M9bMZtPXUji69lmf5Cmamq7quNLFZXD9Rq7v0Bpc1o/tp0fisAAAAASUVORK5CYII=)](https://github.com/marketplace/actions/net-version-sweeper)
8-
[![GitHub License](https://img.shields.io/github/license/dotnet/versionsweeper)](https://github.com/dotnet/versionsweeper/blob/main/LICENSE)
7+
[![GitHub marketplace](https://img.shields.io/badge/marketplace-.NET%20version%20sweeper-green?colorA=24292e&colorB=97ca00&style=flat&longCache=true&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAM6wAADOsB5dZE0gAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAERSURBVCiRhZG/SsMxFEZPfsVJ61jbxaF0cRQRcRJ9hlYn30IHN/+9iquDCOIsblIrOjqKgy5aKoJQj4O3EEtbPwhJbr6Te28CmdSKeqzeqr0YbfVIrTBKakvtOl5dtTkK+v4HfA9PEyBFCY9AGVgCBLaBp1jPAyfAJ/AAdIEG0dNAiyP7+K1qIfMdonZic6+WJoBJvQlvuwDqcXadUuqPA1NKAlexbRTAIMvMOCjTbMwl1LtI/6KWJ5Q6rT6Ht1MA58AX8Apcqqt5r2qhrgAXQC3CZ6i1+KMd9TRu3MvA3aH/fFPnBodb6oe6HM8+lYHrGdRXW8M9bMZtPXUji69lmf5Cmamq7quNLFZXD9Rq7v0Bpc1o/tp0fisAAAAASUVORK5CYII=)](https://github.com/marketplace/actions/net-version-sweeper)
8+
[![GitHub license](https://img.shields.io/github/license/dotnet/versionsweeper)](https://github.com/dotnet/versionsweeper/blob/main/LICENSE)
99
[![GitHub contributors](https://img.shields.io/github/contributors/dotnet/versionsweeper.svg)](https://GitHub.com/dotnet/versionsweeper/graphs/contributors/)
1010
[![GitHub repo size](https://img.shields.io/github/repo-size/dotnet/versionsweeper)](https://github.com/dotnet/versionsweeper)
1111
[![GitHub issues-opened](https://img.shields.io/github/issues/dotnet/versionsweeper.svg)](https://GitHub.com/dotnet/versionsweeper/issues?q=is%3Aissue+is%3Aopened)
@@ -16,7 +16,7 @@
1616

1717
## Get started
1818

19-
The .NET version sweeper is designed to alert repositories that there are projects targeting versions that are no longer supported. For example, projects targeting .NET Core 3.0, or .NET Framework 4.5.1 would trigger an issue to be created to update these non-LTS or current versions. For example issues, see [issues created in this repo based on the *non-lts* directory](https://github.com/dotnet/versionsweeper/issues?q=is%3Aopen+is%3Aissue+label%3Adotnet-target-version).
19+
The .NET version sweeper is designed to alert repositories (by either creating issues, pull requests, or both) that there are projects targeting versions that are no longer supported (or won't be soon). For example, projects targeting .NET Core 3.0 or .NET Framework 4.5.1 could trigger an issue to be created to update these projects to supported versions, or even a pull request that upgrades it for you. For example issues, see [issues created in this repo based on the *non-lts* directory](https://github.com/dotnet/versionsweeper/issues?q=is%3Aopen+is%3Aissue+label%3Adotnet-target-version).
2020

2121
This is intended to be used as a GitHub action that will run as a [scheduled CRON job](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#onschedule). Ideally, once a month or as often as necessary to align with .NET version updates.
2222

@@ -39,56 +39,103 @@ A schedule/cron job that runs on the first of every month is detailed below in t
3939
| `-p`, `pattern` | The search pattern, defaults to `"*.csproj;*.fsproj;*.vbproj;*.xproj;project.json"`. |
4040
| `-s`, `sdk-compliance` | Whether or not to report projects that are not using the new SDK-style project format. |
4141

42+
## GitHub Action outputs
43+
44+
| Output | Type | Details |
45+
|:---------------------|:-----------|:-----------------------------------------------------------------------------------------------------------|
46+
| `has-remaining-work` | `bool` | When `true`, the `upgrade-projects` array will be populated with project directories that require upgrade. |
47+
| `upgrade-projects` | `string[]` | An array of project directories that are in need of being upgraded. |
48+
49+
> **Note**
50+
> Outputs are only present when configured to run as pull request mode. For more information, see [Configure action](#configure-action).
51+
4252
## Example workflow
4353

4454
```yml
45-
# The name used in the GitHub UI for the workflow
46-
name: '.net version sweeper'
55+
# This is a basic workflow to help you get started with Actions
4756

48-
# When to run this action:
49-
# - Scheduled on the first of every month
50-
# - Manually runable from the GitHub UI with a reason
57+
name: "target supported version"
58+
59+
# Controls when the action will run.
5160
on:
61+
# Triggers the workflow on push or pull request events but only for the default branch
5262
schedule:
53-
- cron: '0 0 1 * *'
63+
- cron: "0 0 1 * *"
5464
workflow_dispatch:
5565
inputs:
5666
reason:
57-
description: 'The reason for running the workflow'
67+
description: "The reason for running the workflow"
68+
required: true
69+
default: "Manual run"
70+
support:
71+
description: "The support level to target (STS, LTS, or Preview)."
5872
required: true
59-
default: 'Manual run'
73+
default: "STS"
6074

61-
# Run on the latest version of Ubuntu
75+
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
6276
jobs:
77+
# This workflow contains a single job called "build"
6378
version-sweep:
79+
# The type of runner that the job will run on
6480
runs-on: ubuntu-latest
6581
permissions:
66-
contents: read
6782
issues: write
68-
statuses: write
83+
pull-requests: write
6984

70-
# Checkout the repo into the workspace within the VM
85+
# Steps represent a sequence of tasks that will be executed as part of the job
7186
steps:
72-
- uses: actions/checkout@v2
73-
74-
# If triggered manually, print the reason why
75-
- name: 'Print manual run reason'
76-
if: ${{ github.event_name == 'workflow_dispatch' }}
77-
run: |
78-
echo "Reason: ${{ github.event.inputs.reason }}"
79-
80-
# Run the .NET version sweeper
81-
# Issues will be automatically created for any non-ignored projects that are targeting non-LTS versions
82-
- name: .NET version sweeper
83-
id: dotnet-version-sweeper
84-
uses: dotnet/versionsweeper@v1.2
85-
env:
86-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
87-
with:
88-
owner: ${{ github.repository_owner }}
89-
name: ${{ github.repository }}
90-
branch: ${{ github.ref }}
91-
sdkCompliance: true
87+
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
88+
- uses: actions/checkout@v3
89+
90+
# Runs a single command using the runners shell
91+
- name: "Print manual run reason"
92+
if: ${{ github.event_name == 'workflow_dispatch' }}
93+
run: |
94+
echo 'Reason: ${{ github.event.inputs.reason }}'
95+
96+
# Start the .NET version sweeper, scan projects/slns for non-LTS (or currrent) versions
97+
- name: .NET version sweeper
98+
id: dotnet-version-sweeper
99+
uses: dotnet/versionsweeper@main
100+
env:
101+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
102+
with:
103+
owner: ${{ github.repository_owner }}
104+
name: ${{ github.repository }}
105+
branch: ${{ github.ref }}
106+
107+
- name: Create pull requests
108+
if: steps.dotnet-version-sweeper.outputs.has-remaining-work == 'true'
109+
run: |
110+
upgradeProjects: ${{ steps.dotnet-version-sweeper.outputs.upgrade-projects }}
111+
112+
# Install .NET Upgrade Assistant global tool
113+
dotnet tool install --global upgrade-assistant
114+
115+
# Iterate all upgrade projects
116+
for projectDir in "${upgradeProjects[@]}"; do
117+
echo "Project Directory: $projectDir"
118+
119+
# Create a new branch
120+
git checkout -b upgrade/$projectDir
121+
122+
# Perform the upgrade using upgrade-assistant
123+
upgrade-assistant upgrade "$projectDir" --non-interactive -t ${{ inputs.support }}
124+
125+
# Commit the changes
126+
git add .
127+
git commit -m ".NET Version Sweeper: Upgraded $projectDir"
128+
129+
# Push the branch to the repository
130+
git push origin upgrade/$projectDir
131+
132+
# Create a pull request
133+
gh pr create \
134+
--base main \
135+
--head upgrade/$projectDir \
136+
--title "Upgraded $projectDir" \
137+
--body "Proposed upgrade for $projectDir"
138+
done
92139
```
93140
94141
## Project and solution discovery
@@ -102,6 +149,13 @@ The .NET version sweeper currently supports reporting on all of the following ty
102149
- Project JSON files: `project.json`
103150
- Solution files: `*.sln`
104151

152+
## Dockerfile discovery
153+
154+
The .NET version sweeper also supports reporting _Dockerfile_ target frameworks that are out-of-support, or soon to be, for example:
155+
156+
- `FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8`
157+
- `COPY --from=mcr.microsoft.com/dotnet/framework/runtime:3.5-20221011-windowsservercore-ltsc2019`
158+
105159
## Configure action
106160

107161
To configure the action, you can create a file at the root of the repository named *dotnet-versionsweeper.json*. This config file contains a node, named `"ignore"` that is an array of patterns following the [globbing matcher detailed here](https://docs.microsoft.com/dotnet/api/microsoft.extensions.filesystemglobbing.matcher#remarks).
@@ -115,12 +169,19 @@ The file can also contain a value `outOfSupportWithinDays` to specify the number
115169
"**/*ThisShouldNeverBeFlagged.csproj",
116170
"IgnoreDir/**/*.*"
117171
],
118-
"outOfSupportWithinDays": 90
172+
"outOfSupportWithinDays": 90,
173+
"actionType": "All"
119174
}
120175
```
121176

122177
For an example config file, see [dotnet/samples/dotnet-versionsweeper.json](https://github.com/dotnet/samples/blob/master/dotnet-versionsweeper.json).
123178

179+
| Configuration | Type | Details |
180+
|:--|:--|:--|
181+
| `ignore` | `string[]` | Glob patterns to ignore. |
182+
| `outOfSupportWithinDays` | `string[]` | The number of days in advance to monitor for. |
183+
| `actionType` | `ActionType` <br><br> &nbsp;&nbsp; `"CreateIssue"` <br> &nbsp;&nbsp; `"PullRequest"` <br> &nbsp;&nbsp; `"All"` | The type of action to take, defaults to `CreateIssue`. |
184+
124185
## Label auto-generation
125186

126187
This tool will create a label named `dotnet-target-version` for easier tracking of issues and pull requests that it creates. The label is created with the following description and color by default, please do not change the name - as that is what is used to determine whether or not to create a new label.
@@ -140,7 +201,7 @@ This repo serves as a sample, as it contains a directory *non-lts* with projects
140201

141202
## Official .NET support policies
142203

143-
This action is intended to help determine non-LTS (or current) versions, but it is _not_ perfect. When in doubt, please refer to the [official .NET support policies](https://dotnet.microsoft.com/platform/support/policy).
204+
This action is intended to help determine non-LTS (or STS) versions, but it _isn't_ perfect. When in doubt, please refer to the [official .NET support policies](https://dotnet.microsoft.com/platform/support/policy).
144205

145206
## Acknowledgements
146207

action.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ inputs:
2626
required: false
2727
default: 'false'
2828
outputs:
29-
summary-message:
30-
description: 'A detailed summary of all the projects that were flagged.'
29+
has-remaining-work:
30+
description: 'A boolean value indicating whether more work remains, i.e. upgrade-projects contains values.'
31+
upgrade-projects:
32+
description: 'An array of projects that need to be upgraded.'
3133
runs:
3234
using: 'docker'
3335
image: 'Dockerfile'
@@ -43,4 +45,4 @@ runs:
4345
- '-p'
4446
- ${{ inputs.pattern }}
4547
- '-s'
46-
- ${{ inputs.sdkCompliance }}
48+
- ${{ inputs.sdkCompliance }}

src/DotNet.GitHub/DotNet.GitHub.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<TargetFramework>net7.0</TargetFramework>
@@ -11,8 +11,8 @@
1111
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="7.0.0" />
1212
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
1313
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" />
14-
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.0" />
15-
<PackageReference Include="Octokit" Version="6.0.0" />
14+
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" />
15+
<PackageReference Include="Octokit" Version="7.0.1" />
1616
</ItemGroup>
1717

1818
<ItemGroup>

src/DotNet.GitHub/GitHubGraphQLClient.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public GitHubGraphQLClient(HttpClient httpClient, ILogger<GitHubGraphQLClient> l
7272
}
7373
catch (Exception ex)
7474
{
75-
_logger.LogWarning(ex, ex.Message);
75+
_logger.LogWarning(ex, "⚠️ {Message}", ex.Message);
7676

7777
return (true, default);
7878
}

src/DotNet.GitHub/GitHubIssueService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public async ValueTask<Issue> PostIssueAsync(
2424
IIssuesClient issuesClient = GetIssuesClient(token);
2525
Issue issue = await issuesClient.Create(owner, name, newIssue);
2626

27-
_logger.LogInformation($"Issue created: {issue.HtmlUrl}");
27+
_logger.LogInformation("Issue created: {HtmlUrl}", issue.HtmlUrl);
2828

2929
return issue;
3030
}
@@ -40,7 +40,7 @@ public async ValueTask<Issue> UpdateIssueAsync(
4040
Issue issue = await issuesClient.Update(
4141
owner, name, unchecked((int)number), issueUpdate);
4242

43-
_logger.LogInformation($"Issue updated: {issue.HtmlUrl}");
43+
_logger.LogInformation("Issue updated: {HtmlUrl}", issue.HtmlUrl);
4444

4545
return issue;
4646
}

src/DotNet.GitHub/ModelExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ The following project file(s) target a .NET version which is no longer supported
5151
})));
5252

5353
document.AppendParagraph(
54-
"Consider upgrading projects to either the current release, or the nearest LTS TFM version.");
54+
"Consider upgrading projects to either the Standard Term Support (STS) or Long Term Support (LTS) versions.");
5555

5656
document.AppendParagraph($"""
5757
If any of these projects listed in this issue are intentionally targeting an unsupported version,
@@ -122,7 +122,7 @@ The following Dockerfile(s) target a .NET version which is no longer supported.
122122
})));
123123

124124
document.AppendParagraph(
125-
"Consider upgrading Dockerfile images to either the current release, or the nearest LTS TFM version.");
125+
"Consider upgrading Dockerfile images to either the Standard Term Support (STS) or Long Term Support (LTS) versions.");
126126

127127
document.AppendParagraph($"""
128128
If any of these Dockerfile(s) listed in this issue are intentionally targeting an unsupported version,

src/DotNet.GitHub/RateLimitAwareQueue.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ public sealed class RateLimitAwareQueue
77
{
88
const int DelayBetweenPostCalls = 1_000;
99

10-
readonly HashSet<string> _unqiueNewIssueTitles = new(StringComparer.OrdinalIgnoreCase);
10+
readonly HashSet<string> _uniqueTitles = new(StringComparer.OrdinalIgnoreCase);
1111
readonly ConcurrentQueue<(GitHubApiArgs, NewIssue)> _newIssuesQueue = new();
1212
readonly ConcurrentQueue<(GitHubApiArgs, IssueUpdate)> _updateIssuesQueue = new();
1313
readonly IGitHubIssueService _gitHubIssueService;
@@ -17,7 +17,7 @@ public RateLimitAwareQueue(IGitHubIssueService gitHubIssueService) =>
1717

1818
public void Enqueue(GitHubApiArgs args, NewIssue issue)
1919
{
20-
if (_unqiueNewIssueTitles.Add(issue.Title))
20+
if (_uniqueTitles.Add(issue.Title))
2121
{
2222
_newIssuesQueue.Enqueue((args, issue));
2323
}
@@ -26,7 +26,7 @@ public void Enqueue(GitHubApiArgs args, NewIssue issue)
2626
public void Enqueue(GitHubApiArgs args, IssueUpdate issue) =>
2727
_updateIssuesQueue.Enqueue((args, issue));
2828

29-
public async IAsyncEnumerable<(string Type, Issue Issue)> ExecuteAllQueuedItemsAsync()
29+
public async IAsyncEnumerable<(string Message, string Url)> ExecuteAllQueuedItemsAsync()
3030
{
3131
while (_newIssuesQueue is { IsEmpty: false }
3232
&& _newIssuesQueue.TryDequeue(out (GitHubApiArgs, NewIssue) newItem))
@@ -35,7 +35,7 @@ public void Enqueue(GitHubApiArgs args, IssueUpdate issue) =>
3535
Issue issue = await _gitHubIssueService.PostIssueAsync(
3636
args.Owner, args.RepoName, args.Token, newIssue);
3737

38-
yield return ("Created", issue);
38+
yield return ("Created issue", issue.HtmlUrl);
3939

4040
await Task.Delay(DelayBetweenPostCalls);
4141
}
@@ -47,7 +47,7 @@ public void Enqueue(GitHubApiArgs args, IssueUpdate issue) =>
4747
Issue issue = await _gitHubIssueService.UpdateIssueAsync(
4848
args.Owner, args.RepoName, args.Token, args.IssueNumber, newIssue);
4949

50-
yield return ("Updated", issue);
50+
yield return ("Updated issue", issue.HtmlUrl);
5151

5252
await Task.Delay(DelayBetweenPostCalls);
5353
}

0 commit comments

Comments
 (0)