Skip to content

Commit 201129f

Browse files
Merge pull request #3 from mod-posh/dev
Version 1.3.0
2 parents 42f55f5 + 716580c commit 201129f

File tree

9 files changed

+338
-0
lines changed

9 files changed

+338
-0
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,20 @@ All changes to this module should be reflected in this document.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [[1.3.0]](https://github.com/mod-posh/LocalAutomation/releases/tag/v1.3.0) - 2024-01-05
9+
10+
This release adds support for CSharp Projects
11+
12+
1. CSharpProject
13+
1. Updated the psake to support C# projects
14+
1. Added a check for git setup
15+
2. Added a check for DefaultDocumentation nuget tool
16+
3. Updated most of the tasks to work with C#
17+
4. Added BlueSky as a notification option
18+
2. Updated the nuget.config to work with nuget.org properly
19+
20+
---
21+
822
## [[1.2.0]](https://github.com/mod-posh/LocalAutomation/releases/tag/v1.2.0) - 2023-06-27
923

1024
This release updated a few issues with the CsharpModule
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net7.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
</PropertyGroup>
8+
9+
</Project>

CSharpProject/CSharpProject/Class1.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace CSharpProject;
2+
3+
public class Class1
4+
{
5+
6+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Use the PowerShell extension setting `powershell.scriptAnalysis.settingsPath` to get the current workspace
2+
# to use this PSScriptAnalyzerSettings.psd1 file to configure code analysis in Visual Studio Code.
3+
# This setting is configured in the workspace's `.vscode\settings.json`.
4+
#
5+
# For more information on PSScriptAnalyzer settings see:
6+
# https://github.com/PowerShell/PSScriptAnalyzer/blob/master/README.md#settings-support-in-scriptanalyzer
7+
#
8+
# You can see the predefined PSScriptAnalyzer settings here:
9+
# https://github.com/PowerShell/PSScriptAnalyzer/tree/master/Engine/Settings
10+
@{
11+
# Only diagnostic records of the specified severity will be generated.
12+
# Uncomment the following line if you only want Errors and Warnings but
13+
# not Information diagnostic records.
14+
#Severity = @('Error','Warning')
15+
16+
# Analyze **only** the following rules. Use IncludeRules when you want
17+
# to invoke only a small subset of the default rules.
18+
IncludeRules = @('PSAvoidDefaultValueSwitchParameter',
19+
'PSMisleadingBacktick',
20+
'PSMissingModuleManifestField',
21+
'PSReservedCmdletChar',
22+
'PSReservedParams',
23+
'PSShouldProcess',
24+
'PSUseApprovedVerbs',
25+
'PSAvoidUsingCmdletAliases',
26+
'PSUseDeclaredVarsMoreThanAssignments')
27+
28+
# Do not analyze the following rules. Use ExcludeRules when you have
29+
# commented out the IncludeRules settings above and want to include all
30+
# the default rules except for those you exclude below.
31+
# Note: if a rule is in both IncludeRules and ExcludeRules, the rule
32+
# will be excluded.
33+
#ExcludeRules = @('PSAvoidUsingWriteHost')
34+
35+
# You can use rule configuration to configure rules that support it:
36+
Rules = @{
37+
PSAvoidUsingCmdletAliases = @{
38+
Whitelist = @("Task")
39+
}
40+
}
41+
}

CSharpProject/bluesky.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"identifier":"username.bsky.social",
3+
"password":"api-token-key"
4+
}

CSharpProject/discord.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"uri": "https://discord.com/api/webhooks/",
3+
"message": {
4+
"content": "This is a test message"
5+
}
6+
}

CSharpProject/github.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"Token": "github_pat_"
3+
}

CSharpProject/nuget.config

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<configuration>
3+
<config>
4+
<add key="defaultPushSource" value="https://api.nuget.org/v3/index.json" />
5+
</config>
6+
<packageSources>
7+
<clear />
8+
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
9+
</packageSources>
10+
<apikeys>
11+
<add key="raw-from-nuget.org" value="nuget-api-key" />
12+
<add key="https://www.nuget.org" value="encrypted from nuget setapikey nuget-api-ke -configfile .\nuget.config" />
13+
</apikeys>
14+
</configuration>

CSharpProject/psakefile.ps1

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
$script:ProjectName = "CSharpProject"; # The name of your C# Project
2+
$script:DotnetVersion = "net7.0"; # The version of .Net the project is targeted to
3+
$script:GithubOrg = 'Org-or-Username' # This could be your github username if you're not working in a Github Org
4+
$script:Repository = "https://github.com/$($script:GithubOrg)"; # This is the Github Repo
5+
$script:DeployBranch = 'main'; # The branch that we deploy from, typically master or main
6+
$script:Root = $PSScriptRoot; # This will be the root of your Module Project, not the Repository Root
7+
$script:Source = Join-Path $script:Root $script:ProjectName; # This will be the root of your Module Project, not the Repository Root
8+
$script:Output = Join-Path $script:Root 'output'; # The module will be output into this folder
9+
$script:Docs = Join-Path $script:Root 'docs'; # The root folder for the PowerShell Module
10+
$script:TestFile = ("TestResults_$(Get-Date -Format s).xml").Replace(':', '-'); # The Pester Test output file
11+
$script:DiscordChannel = "https://discord.com/channels/" # Discord Channel
12+
$script:NugetOrg = "https://www.nuget.org/packages" # The Nuget.org URL
13+
14+
$PowerShellForGitHub = Get-Module -ListAvailable | Where-Object -Property Name -eq PowerShellForGitHub;
15+
if ($PowerShellForGitHub)
16+
{
17+
Write-Host -ForegroundColor Blue "Info: PowerShellForGitHub Version $($PowerShellForGitHub.Version) Found";
18+
Write-Host -ForegroundColor Blue "Info: This automation built with PowerShellForGitHub Version 0.16.1";
19+
Import-Module PowerShellForGitHub;
20+
}
21+
else
22+
{
23+
throw "Please Install-Module -Name PowerShellForGitHub";
24+
}
25+
$DotnetTools = dotnet tool list --global;
26+
$DefaultDocumentationArray = ($DotnetTools |Select-String 'defaultdocumentation').ToString() -split '\s+';
27+
28+
$DefaultDocumentation = New-Object PSObject -Property @{
29+
PackageId = $DefaultDocumentationArray[0]
30+
Version = $DefaultDocumentationArray[1]
31+
Commands = $DefaultDocumentationArray[2]
32+
}
33+
34+
if ($DefaultDocumentation)
35+
{
36+
Write-Host -ForegroundColor Blue "Info: DefaultDocumentation Version $($DefaultDocumentation.Version) Found";
37+
Write-Host -ForegroundColor Blue "Info: This automation built with PowerShellForGitHub Version 0.8.2";
38+
}
39+
else
40+
{
41+
throw "Please dotnet tool install DefaultDocumentation.Console -g";
42+
}
43+
44+
$gitConfigList =(git config --list) -split '\n';
45+
$gitConfig = @{};
46+
foreach ($str in $gitConfigList) {
47+
# Split the string into a key and a value
48+
$keyValue = $str -split '='
49+
50+
# Add the key-value pair to the hashtable
51+
$gitConfig[$keyValue[0]] = $keyValue[1]
52+
}
53+
54+
if ($gitConfig['user.email'] -and $gitConfig['user.name'])
55+
{
56+
Write-Host -ForegroundColor Blue "Info: Git Config has been setup";
57+
}
58+
else
59+
{
60+
throw "please run git config user.email, git config user.name"
61+
}
62+
63+
Write-Host -ForegroundColor Green "ProjectName : $($script:ProjectName)";
64+
Write-Host -ForegroundColor Green "DotnetVersion : $($script:DotnetVersion)";
65+
Write-Host -ForegroundColor Green "GithubOrg : $($script:GithubOrg)";
66+
Write-Host -ForegroundColor Green "Root : $($script:Root)";
67+
Write-Host -ForegroundColor Green "Source : $($script:Source)";
68+
Write-Host -ForegroundColor Green "Output : $($script:Output)";
69+
Write-Host -ForegroundColor Green "Docs : $($script:Docs)";
70+
Write-Host -ForegroundColor Green "TestFile : $($script:TestFile)";
71+
Write-Host -ForegroundColor Green "Repository : $($script:Repository)";
72+
Write-Host -ForegroundColor Green "DiscordChannel : $($script:DiscordChannel)";
73+
Write-Host -ForegroundColor Green "NugetOrg : $($script:NugetOrg)";
74+
Write-Host -ForegroundColor Green "DeployBranch : $($script:DeployBranch)";
75+
76+
Task default -depends LocalUse
77+
Task LocalUse -Description "Setup for local use and testing" -depends Clean, BuildProject
78+
Task Build -depends LocalUse, TestProject
79+
Task Package -depends UpdateReadme, CreateDocumentation, PackageProject
80+
Task Deploy -depends CheckBranch, ReleaseNotes, PublishProject, NewTaggedRelease
81+
Task Notifications -depends Post2Discord, Post2Bluesky
82+
83+
Task Clean -depends CleanProject {
84+
$null = Remove-Item $script:Output -Recurse -ErrorAction Ignore
85+
$null = New-Item -Type Directory -Path $script:Output -ErrorAction Ignore
86+
$null = New-Item -Type Directory -Path $script:Docs -ErrorAction Ignore
87+
$null = Remove-Item "$($script:Root)\TestResults*.xml"
88+
}
89+
90+
Task UpdateReadme -Description "Update the README file" -Action {
91+
$Project = [xml](Get-Content -Path "$($script:Source)\$($script:ProjectName).csproj");
92+
$PackageId = $Project.Project.PropertyGroup.PackageId;
93+
$readMe = Get-Item -Path "$($script:Root)\README.md"
94+
95+
$TableHeaders = "| Latest Version | Nuget.org | Issues | License | Discord |"
96+
$Columns = "|-----------------|----------------|----------------|----------------|----------------|"
97+
$VersionBadge = "[![Latest Version](https://img.shields.io/github/v/tag/$($script:GithubOrg)/$($script:ProjectName))]($($script:Repository)/$($script:ProjectName)/tags)"
98+
$GalleryBadge = "[![Nuget.org](https://img.shields.io/nuget/dt/$($PackageId))]($($script:NugetOrg)/$($PackageId))"
99+
$IssueBadge = "[![GitHub issues](https://img.shields.io/github/issues/$($script:GithubOrg)/$($script:ProjectName))]($($script:Repository)/$($script:ProjectName)/issues)"
100+
$LicenseBadge = "[![GitHub license](https://img.shields.io/github/license/$($script:GithubOrg)/$($script:ProjectName))]($($script:Repository)/$($script:ProjectName)/blob/master/LICENSE)"
101+
$DiscordBadge = "[![Discord Server](https://assets-global.website-files.com/6257adef93867e50d84d30e2/636e0b5493894cf60b300587_full_logo_white_RGB.svg)]($($script:DiscordChannel))"
102+
103+
Write-Output $TableHeaders | Out-File $readMe.FullName -Force
104+
Write-Output $Columns | Out-File $readMe.FullName -Append
105+
Write-Output "| $($VersionBadge) | $($GalleryBadge) | $($IssueBadge) | $($LicenseBadge) | $($DiscordBadge) |" | Out-File $readMe.FullName -Append
106+
107+
Get-Content -Path "$($script:Root)\$($script:ProjectName).md" |Out-File -FilePath $readMe.FullName -Append
108+
}
109+
110+
Task NewTaggedRelease -Description "Create a tagged release" -Action {
111+
$Github = (Get-Content -Path "$($script:Root)\github.json") | ConvertFrom-Json
112+
$Credential = New-Credential -Username ignoreme -Password $Github.Token
113+
Set-GitHubAuthentication -Credential $Credential
114+
$Project = [xml](Get-Content -Path "$($script:Source)\$($script:ProjectName).csproj");
115+
$Version = $Project.Project.PropertyGroup.Version.ToString();
116+
git add .
117+
git commit . -m "$($script:ProjectName) $($Version) Release"
118+
git push
119+
git tag -a v$version -m "$($script:ProjectName) Version $($Version)"
120+
git push origin v$version
121+
New-GitHubRelease -OwnerName $script:GithubOrg -RepositoryName $script:ProjectName -Tag "v$($Version)" -Name "v$($Version)"
122+
}
123+
124+
Task Post2Discord -Description "Post a message to discord" -Action {
125+
$Project = [xml](Get-Content -Path "$($script:Source)\$($script:ProjectName).csproj");
126+
$Version = $Project.Project.PropertyGroup.Version.ToString();
127+
$PackageId = $Project.Project.PropertyGroup.PackageId;
128+
$Discord = Get-Content -Path "$($script:Root)\discord.json" | ConvertFrom-Json
129+
$Discord.message.content = "Version $($version) of $($script:ProjectName) released. Please visit Github ($($script:Repository)/$($script:ProjectName)) or Nuget.org ($($script:NugetOrg)/$($PackageId)) to download."
130+
Invoke-RestMethod -Uri $Discord.uri -Body ($Discord.message | ConvertTo-Json -Compress) -Method Post -ContentType 'application/json; charset=UTF-8'
131+
}
132+
133+
Task Post2Bluesky -Description "Post a message to bsky.app" -Action {
134+
$Project = [xml](Get-Content -Path "$($script:Source)\$($script:ProjectName).csproj");
135+
$Version = $Project.Project.PropertyGroup.Version.ToString();
136+
$PackageId = $Project.Project.PropertyGroup.PackageId;
137+
$createdAt = Get-Date -Format "yyyy-MM-ddTHH:mm:ss.ffffffZ"
138+
# Authenticate
139+
$AuthBody = Get-Content -Path "$($script:Root)\bluesky.json"
140+
$Handle = $AuthBody | ConvertFrom-Json | Select-Object -ExpandProperty Identifier
141+
$Headers = @{}
142+
$Headers.Add('Content-Type', 'application/json')
143+
$Response = Invoke-RestMethod -Uri "https://bsky.social/xrpc/com.atproto.server.createSession" -Method Post -Body $AuthBody -Headers $Headers
144+
# Create post
145+
$Headers.Add('Authorization', "Bearer $($Response.accessJwt)")
146+
$Record = New-Object -TypeName psobject -Property @{
147+
'$type' = "app.bsky.feed.post"
148+
'text' = "Version $($version) of $($script:ProjectName) released. Please visit Github ($($script:Repository)/$($script:ProjectName)) or Nuget.org ($($script:NugetOrg)/$($PackageId)) to download."
149+
"createdAt" = $createdAt
150+
}
151+
$Post = New-Object -TypeName psobject -Property @{
152+
'repo' = $Handle
153+
'collection' = 'app.bsky.feed.post'
154+
record = $Record
155+
}
156+
157+
Invoke-RestMethod -Uri "https://bsky.social/xrpc/com.atproto.repo.createRecord" -Method Post -Body ($Post | ConvertTo-Json -Compress) -Headers $Headers
158+
}
159+
160+
Task CleanProject -Description "Clean the project before building" -Action {
161+
dotnet clean "$($script:Source)\$($script:ProjectName).sln" -c Release
162+
dotnet clean "$($script:Source)\$($script:ProjectName).sln" -c Debug
163+
}
164+
165+
Task CreateDocumentation -Description "Create Docs" -Action {
166+
defaultdocumentation -a "$($script:Source)\bin\Release\$($script:DotnetVersion)\$($script:ProjectName).dll" -o $script:Docs
167+
}
168+
169+
Task BuildProject -Description "Build the project" -Action {
170+
dotnet build "$($script:Root)\$($script:ProjectName)\$($script:ProjectName).csproj" -c Release
171+
}
172+
173+
Task CheckBranch -Description "A test that should fail if we deploy while not on master" -Action {
174+
$branch = git branch --show-current
175+
if ($branch -ne $script:DeployBranch)
176+
{
177+
[System.Net.WebSockets.WebSocketException]$Exception = "You are not on the deployment branch: $($script:DeployBranch)"
178+
[string]$ErrorId = "Git.WrongBranch"
179+
[System.Management.Automation.ErrorCategory]$Category = [System.Management.Automation.ErrorCategory]::InvalidOperation
180+
$PSCmdlet.ThrowTerminatingError(
181+
[System.Management.Automation.ErrorRecord]::new(
182+
$Exception,
183+
$ErrorId,
184+
$Category,
185+
$null
186+
)
187+
)
188+
}
189+
}
190+
191+
Task ReleaseNotes -Description "Create release notes file for project" -Action {
192+
$Github = (Get-Content -Path "$($script:Root)\github.json") | ConvertFrom-Json
193+
$Credential = New-Credential -Username ignoreme -Password $Github.Token
194+
Set-GitHubAuthentication -Credential $Credential
195+
$Milestone = (Get-GitHubMilestone -OwnerName $script:GithubOrg -RepositoryName $script:ProjectName -State Closed | Sort-Object -Descending -Property Number)[0]
196+
if ($Milestone)
197+
{
198+
[System.Text.StringBuilder]$stringbuilder = [System.Text.StringBuilder]::new()
199+
[void]$stringbuilder.AppendLine( "# $($Milestone.title)" )
200+
[void]$stringbuilder.AppendLine( "" )
201+
if ($Milestone.description)
202+
{
203+
[void]$stringbuilder.AppendLine( "$($Milestone.description)" )
204+
}
205+
$i = Get-GitHubIssue -OwnerName $script:GithubOrg -RepositoryName $script:ProjectName -RepositoryType All -Filter All -State Closed -MilestoneNumber $Milestone.Number;
206+
$headings = $i | ForEach-Object { $_.Labels.Name } | Sort-Object -Unique;
207+
foreach ($heading in $headings)
208+
{
209+
[void]$stringbuilder.AppendLine( "" )
210+
[void]$stringbuilder.AppendLine( "## $($heading.ToUpper())" )
211+
[void]$stringbuilder.AppendLine( "" )
212+
$issues = $i | ForEach-Object { if ($_.Labels.Name -eq $Heading) { $_ } }
213+
foreach ($issue in $issues)
214+
{
215+
[void]$stringbuilder.AppendLine( "* $($issue.title) #$($issue.issuenumber)" )
216+
}
217+
}
218+
Out-File -FilePath "$($script:Root)\RELEASE.md" -InputObject $stringbuilder.ToString() -Encoding ascii -Force
219+
$Project = [xml](Get-Content -Path "$($script:Source)\$($script:ProjectName).csproj");
220+
$ReleaseNotes = (Get-Content -Path "$($script:Root)\RELEASE.md").Replace('## ', '-').Replace('# ', '').Replace('*', '-')
221+
$Project.Project.PropertyGroup.PackageReleaseNotes = $ReleaseNotes
222+
$Project.Save("$($script:Source)\$($script:ProjectName).csproj")
223+
}
224+
}
225+
226+
Task TestProject -Description "Test project" -Action {
227+
dotnet test $script:Source\$script:ProjectName.sln --logger "trx;LogFileName=$($script:Root)\$($script:TestFile)"
228+
}
229+
230+
Task PackageProject -Description "Package the project" -Action {
231+
dotnet pack $script:Source\$script:ProjectName.sln -o $script:Output -c Release
232+
}
233+
234+
Task PublishProject -Description "Publish project to Nuget.org" -Action {
235+
$Project = [xml](Get-Content -Path "$($script:Source)\$($script:ProjectName).csproj");
236+
$PackageId = $Project.Project.PropertyGroup.PackageId;
237+
$Version = $Project.Project.PropertyGroup.Version.ToString();
238+
239+
$PackageFile = "$($script:Output)\$($PackageId).$($Version).nupkg"
240+
dotnet nuget push $PackageFile
241+
}

0 commit comments

Comments
 (0)