Skip to content

Commit

Permalink
CI: check the dependency updates automatically
Browse files Browse the repository at this point in the history
  • Loading branch information
ForNeVeR committed Mar 16, 2024
1 parent c27bc03 commit 88d704d
Show file tree
Hide file tree
Showing 2 changed files with 187 additions and 0 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/ps-dependencies.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: "Dependency Checker"
on:
schedule:
- cron: '0 0 * * *' # Every day
workflow_dispatch:

jobs:
main:
runs-on: ubuntu-22.04
timeout-minutes: 15
steps:
- name: "Check out the sources"
uses: actions/checkout@v4

- id: update
name: "Update the dependency versions"
shell: pwsh
run: ./src/scripts/Update-Dependencies.ps1

- if: steps.update.outputs.has-changes == 'true'
name: "Create a PR"
uses: peter-evans/create-pull-request@v6
with:
branch: ${{ steps.update.outputs.branch-name }}
author: "intellij-powershell automation <[email protected]>"
commit-message: ${{ steps.update.outputs.commit-message }}
title: ${{ steps.update.outputs.pr-title }}
body-path: ${{ steps.update.outputs.pr-body-path }}
159 changes: 159 additions & 0 deletions src/scripts/Update-Dependencies.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
<#
.DESCRIPTION
This script will update the PowerShell modules used by the plugin.
#>
param (
$SourceRoot = "$PSScriptRoot/../..",
$GradleProperties = "$SourceRoot/gradle.properties"
)

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

function ReadCurrentVersions
{
$properties = @{}
foreach ($line in Get-Content $GradleProperties)
{
if ($line.Trim().StartsWith('#') -or $line.Trim().Length -eq 0)
{
continue
}
$pair = $line.Split('=', 2)
$properties[$pair[0].Trim()] = $pair[1].Trim()
}

@{
PSScriptAnalyzer = [Version] $properties['psScriptAnalyzerVersion']
PowerShellEditorServices = [Version] $properties['psesVersion']
}
}

$psScriptAnalyzer = Invoke-RestMethod `
'https://api.github.com/repos/PowerShell/PSScriptAnalyzer/releases?per_page=1'
$pses = Invoke-RestMethod 'https://api.github.com/repos/PowerShell/PowerShellEditorServices/releases?per_page=1'

function ReadLatestVersions
{
@{
PSScriptAnalyzer = [Version] $psScriptAnalyzer.tag_name
PowerShellEditorServices = [Version] $pses.tag_name.Trim('v')
}
}

function FetchVersionDetails($dependency)
{
$details = switch ($dependency)
{
'PSScriptAnalyzer' { $psScriptAnalyzer }
'PowerShellEditorServices' { $pses }
default { throw "Unknown dependency: $dependency" }
}
if ($details.assets.Count -gt 1)
{
throw "Dependency $dependency has more than 1 release asset ($($details.assets.Count))."
}

$releaseAsset = $details.assets[0]
@{
Name = $dependency
Version = $details.tag_name.Trim('v')
ReleaseNotes = $details.body
DownloadUrl = $releaseAsset.browser_download_url
}
}

function UpdateProperty($text, $key, $value)
{
$text -replace "$([Regex]::Escape($key))=[^\n]*", "$key=$value"
}

function UpdateProperties($properties, $updates, $hashes)
{
foreach ($dependency in $updates.Keys)
{
$key = switch ($dependency)
{
'PSScriptAnalyzer' { 'psScriptAnalyzer' }
'PowerShellEditorServices' { 'pses' }
default { throw "Unknown dependency: $dependency" }
}
$properties = UpdateProperty $properties "$($key)Version" $updates[$dependency].Version
$properties = UpdateProperty $properties "$($key)Sha256Hash" $hashes[$dependency]
}

$properties
}

function GetArtifactHashes($updates)
{
$hashes = @{}
foreach ($dependency in $updates.Keys)
{
$tempFile = New-TemporaryFile
Invoke-RestMethod $updates[$dependency].DownloadUrl -OutFile $tempFile
$hash = (Get-FileHash -Algorithm SHA256 $tempFile).Hash
$hashes[$dependency] = $hash
}
$hashes
}

function ApplyUpdates($updates)
{
$properties = Get-Content -Raw $GradleProperties
$hashes = GetArtifactHashes $updates
$newContent = UpdateProperties $properties $updates $hashes
[IO.File]::WriteAllText($GradleProperties, $newContent)
}

$currentVersions = ReadCurrentVersions
$latestVersions = ReadLatestVersions
$updates = @{ }

foreach ($dependency in $currentVersions.Keys)
{
$currentVersion = $currentVersions[$dependency]
$latestVersion = $latestVersions[$dependency]
if ($latestVersion -gt $currentVersion)
{
Write-Host "A dependency $dependency has version $currentVersion and can be updated to $latestVersion."
$updates[$dependency] = FetchVersionDetails $dependency
}
}

$hasChanges = $updates.Count -gt 0
if ($hasChanges)
{
$branchName = 'dependencies' + ($updates.Keys -join '+')
[array] $versionUpdateStrings = $updates.Values | ForEach-Object { "$($_.Name) to v$($_.Version)" }
$prTitle = 'Update ' + ($versionUpdateStrings -join ' and ')
$commitMessage = $prTitle
[array] $updateReleaseNoteStrings = $updates.Values | ForEach-Object {
@"
## $($_.Name) v$($_.Version)
$($_.ReleaseNotes)
"@
}
$prBody = $updateReleaseNoteStrings -join "`n"
}

ApplyUpdates $updates

$result = if ($hasChanges)
{
$prBodyPath = New-TemporaryFile
$prBody > $prBodyPath
@"
has-changes=true
branch-name=$branchName
commit-message=$commitMessage
pr-title=$prTitle
pr-body-path=$prBodyPath
"@
}
else
{
'has-changes=false'
}

$result >> $env:GITHUB_OUTPUT

0 comments on commit 88d704d

Please sign in to comment.