Skip to content

asheroto/Chocolatey-Package-Updater

Repository files navigation

Chocolatey-Package-Updater

Chocolatey Package Updater screenshot

GitHub Release Date - Published_At GitHub Downloads - All Releases GitHub Sponsor Ko-Fi Button

Brand new and under development but is currently working! 😊

Chocolatey-Package-Updater is a PowerShell script designed to automate the update of a Chocolatey package's version and checksum, as well as send an alert to the maintainer for review.

UpdateFunctions.ps1 can be placed anywhere, but ideally at the root of you Chocolatey packages repository, with your packages being subfolders underneath. Then you can dot-source this script to access the function UpdateChocolateyPackage.

Inspiration

Thie package was inspired by the Chocolatey Automatic Package Updater Module but that project is no longer maintained and I wanted to create something that was more lightweight and easier to use. The goal is to make it as easy as possible to update your Chocolatey packages without having to write regex or much more than a few lines of code.

Features

The UpdateChocolateyPackage function provides the following features:

  • No functions or regex to write: everything happens automatically!
  • Regex expressions only required if scraping version number from a URL.
  • Updates the version in the nuspec file.
  • Updates the url/checksum and url64/checksum64 (if specified) in the ChocolateyInstall.ps1 script.
  • Updates the checksum and checksum64 (if specified) in the VERIFICATION.txt file (if it exists).
  • Updates the version number in the download URL (if specified).
  • Sends an alert to a designated URL.
  • Supports EXE files distributed in the package.
  • Supports variable and hash table formats for checksum in the ChocolateyInstall.ps1 script.
  • Supports single and double quotes for checksum in the ChocolateyInstall.ps1 script.
  • Automatic support for aria2 download manager as well as Invoke-WebRequest.
  • Supports scraping the version number from the download URL.
  • Supports version number replacement in the download URL.
  • Supports getting the latest version from a GitHub repository.
  • Coming soon: support for ntfy to send alerts to many other services (email, Discord, Telegram, PagerDuty, Twilio, etc.)
  • Coming soon: dot-sourcing the script will not be required.

Note: This is a rather new project, being born in late September 2023. There may still be some bugs. For now, check out the example packages to see how it works. Also check out the To-Do List for upcoming features.

Important

Alterting does not work at this time but will in the next few weeks. I'm working on adding native support for other services. You can use $Alert = false to disable alerting for now or update the SendAlertRaw function to use your own service.

Requirements

  • PowerShell 7+
  • Windows Terminal recommended but not required

Installation

Note

An installer is not available yet, but for now you can follow the instructions below.

For the initial setup, a few short steps are required that takes less than 5 minutes. After that, you can simply copy and paste the update.ps1 script and change the parameters as needed.

  1. Download the Chocolatey-Package-Updater.ps1 script from the latest release.
  2. Move the downloaded script into the root directory of your Chocolatey packages repository like the Recommended Folder Structure below.
  3. Create an update.ps1 file within the folder of your specific Chocolatey package (or copy the example package from this repository).
  4. Make the functions from Chocolatey-Package-Updater.ps1 available in your update.ps1 file by dot-sourcing it.
  5. Call the UpdateChocolateyPackage function, passing in the necessary parameters using the examples below.
Recommended Folder Structure

Recommended Folder Structure

The recommended folder structure matches this repository's structure. You can use this as a template for your own Chocolatey packages repository.

Your folder may be called "ChocolateyPackages" and then instead of example-package-exe-distributed, for example, it would be fxsound or whatever your package name is.

image

Certainly, here's a simplified explanation:

Real-World Example

For a practical example of how to set up your Chocolatey packages, you can check out this GitHub repository. This repository shows you how to organize your Chocolatey packages.

[!NOTE] Not every package in this example is using the Chocolatey-Package-Updater.ps1 script yet, but they will be updated to use it soon. To see which packages are already using the updater script, take a look at the UpdateAll.ps1 file in the same repository.

Usage

Before we get too deep into the usage, here are the included example packages. If the code block examples are confusing to you, you can check out the example packages to see how it works.

Example Packages

Package Description
fxsound Uses FileUrl and FileDestinationPath for distributing EXE within package
Miro Uses FileUrl and FileUrl64 for updating a package with both 32/64-bit EXEs
StartAllBack Uses ScrapePattern, ScrapeUrl, and FileUrl for scraping version number from a URL, uses {VERSION} in FileUrl to be replaced by scraping
Ventoy Uses GitHubRepoUrl and FileUrl for downloading the latest release from a GitHub repository

Dot-sourcing the main script (required at the top of each update.ps1)

Note: The $ScriptPath variable must be defined so that the UpdateChocolateyPackage function can locate the package files. Whether you hard code the variable or use the code below, it's up to you.

Required code at the top of any update.ps1 script

# Set vars to the script and the parent path ($ScriptPath MUST be defined for the UpdateChocolateyPackage function to work)
$ScriptPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
$ParentPath = Split-Path -Parent $ScriptPath

# Import the UpdateChocolateyPackage function
. (Join-Path $ParentPath 'Chocolatey-Package-Updater.ps1')

Calling the UpdateChocolateyPackage function

Now that you have the dot-sourcing code at the top of your update.ps1 script, you can call the UpdateChocolateyPackage function immediately after.

Example using file distributed in package

This method corresponds to the example-package-exe-distributed example package.

# Create a hash table to store package information
$packageInfo = @{
    PackageName         = "fxsound"
    FileUrl             = 'https://download.fxsound.com/fxsoundlatest'   # URL to download the file from
    FileDestinationPath = '.\tools\fxsound_setup.exe'                    # Path to move/rename the temporary file to (if EXE is distributed in package
    Alert               = $true                                          # If the package is updated, send a message to the maintainer for review
}

# Call the UpdateChocolateyPackage function and pass the hash table
UpdateChocolateyPackage @packageInfo
Full Example

[CmdletBinding()] # Enables -Debug parameter for troubleshooting
param ()

# Set vars to the script and the parent path ($ScriptPath MUST be defined for the UpdateChocolateyPackage function to work)
$ScriptPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
$ParentPath = Split-Path -Parent $ScriptPath

# Import the UpdateChocolateyPackage function
. (Join-Path $ParentPath 'Chocolatey-Package-Updater.ps1')

# Create a hash table to store package information
$packageInfo = @{
    PackageName         = "fxsound"
    FileUrl             = 'https://download.fxsound.com/fxsoundlatest'   # URL to download the file from
    FileDestinationPath = '.\tools\fxsound_setup.exe'                    # Path to move/rename the temporary file to (if EXE is distributed in package
    Alert               = $true                                          # If the package is updated, send a message to the maintainer for review
}

# Call the UpdateChocolateyPackage function and pass the hash table
UpdateChocolateyPackage @packageInfo

Example using url and url64:

This method corresponds to the example-package-url-url64 example package.

# Create a hash table to store package information
$packageInfo = @{
    PackageName = "miro"
    FileUrl     = 'https://desktop.miro.com/platforms/win32-x86/Miro.exe'   # URL to download the file from
    FileUrl64   = 'https://desktop.miro.com/platforms/win32/Miro.exe'       # URL to download the file from
    Alert       = $true                                                     # If the package is updated, send a message to the maintainer for review
}

# Call the UpdateChocolateyPackage function and pass the hash table
UpdateChocolateyPackage @packageInfo

Example using ScrapeUrl, ScrapePattern, FileUrl version replacement

This method corresponds to the example-package-scrape-version example package.

# Create a hash table to store package information
$packageInfo = @{
    PackageName   = "StartAllBack"                                                                                  # Package name
    ScrapeUrl     = 'https://startallback.com/'                                                                     # URL to scrape for version number
    ScrapePattern = '(?<=<span class="title">Download v)[\d.]+'                                                     # Regex pattern to match version number
    FileUrl       = "https://startisback.sfo3.cdn.digitaloceanspaces.com/StartAllBack_{VERSION}_setup.exe"          # URL to download the file from
}

# Call the UpdateChocolateyPackage function and pass the hash table
UpdateChocolateyPackage @packageInfo

Example using GitHub release

This method corresponds to the example-package-github-repo example package.

# Create a hash table to store package information
$packageInfo = @{
    PackageName   = "ventoy"
    FileUrl       = "https://github.com/ventoy/Ventoy/releases/download/v{VERSION}/ventoy-{VERSION}-windows.zip"
    GitHubRepoUrl = "https://github.com/ventoy/Ventoy"
}

# Call the UpdateChocolateyPackage function and pass the hash table
UpdateChocolateyPackage @packageInfo

Alternate method using named parameters

The splatting method above is recommended because it's easier to read and maintain, but if you'd rather use named parameters, you can do so like this:

UpdateChocolateyPackage -PackageName "fxsound" -FileUrl "https://download.fxsound.com/fxsoundlatest" -FileDestinationPath ".\tools\fxsound_setup.exe" -Alert $true
UpdateChocolateyPackage -PackageName "fxsound" -FileUrl "https://desktop.miro.com/platforms/win32-x86/Miro.exe" -FileUrl64 'https://desktop.miro.com/platforms/win32/Miro.exe' -Alert $true
UpdateChocolateyPackage -PackageName "StartAllBack" -ScrapeUrl 'https://startallback.com/' -ScrapePattern '(?<=<span class="title">Download v)[\d.]+' -FileUrl "https://startisback.sfo3.cdn.digitaloceanspaces.com/StartAllBack_{VERSION}_setup.exe"
UpdateChocolateyPackage -PackageName "ventoy" -FileUrl "https://github.com/ventoy/Ventoy/releases/download/v{VERSION}/ventoy-{VERSION}-windows.zip" -GitHubRepoUrl "https://github.com/ventoy/Ventoy"

Scheduling the PowerShell Script

You can use Windows Task Scheduler to schedule the update.ps1 script to run automatically. It is recommended that you create an UpdateAll.ps1 script in the same folder as Chocolatey-Package-Updater.ps1 and schedule that script to run. See the UpdateAll.ps1 script in this repository for an example.

In Task Scheduler, create a new Task (not basic) and set the Action to the following:

pwsh -Command "& 'YOUR_SCRIPT_PATH_HERE'"

for example

pwsh -Command "& 'C:\Projects\ChocolateyPackages\UpdateAll.ps1'"

or if you don't want to use the UpdateAll.ps1 script, you can use the update.ps1 script of the package directly:

pwsh -Command "& 'C:\Projects\ChocolateyPackages\fxsound\update.ps1'"

Recommended options:

  • Run with the highest privileges
    • To avoid permission issues
  • Run whether user is logged in or not
    • Will make the script run behind-the-scenes as well as hide the window. If you'd rather not use this, you can use my tool SpawnProcess and use SpawnProcess.exe or SpawnProcessHidden.exe which will launch a hidden. Example usage.
  • Schedule as often as you'd like, usually weekly or daily. Recommended twice a week, not more than once per day.
  • Consider changing the power/battery options in the Conditions tab.

Function Parameters for UpdateChocolateyPackage

Parameter Type Required Description
-PackageName string Yes The name of the package.
-FileUrl string Yes The URL to download the file from. If you're using ScrapeUrl and ScrapePattern you can specify {VERSION} in the FileUrl and it will download from that FileUrl.
-FileUrl64 string Yes The URL to download the file from.
-FileDestinationPath string Only required if EXE distributed in package Absolute/relative path to move/rename the temporary file to (if EXE is distributed in package).
-FileDestinationPath64 string Only required if url and url64 is used and EXE is distributed in package Absolute/relative path to move/rename the temporary file to (if EXE is distributed in package).
-GitHubRepoUrl string No The URL to the GitHub repository. If specified, the latest release will be downloaded using {VERSION} replacement in the FileUrl.
-ScrapeUrl string No If the version number is not available in the download URL, you can specify a URL to scrape the version number from.
-ScrapePattern string No The regex pattern to use when scraping the version number from the scrape URL.
-Alert boolean No If the package is updated, send a message to the maintainer for review
-NuspecPath string No Not recommended. Recommended using default Choco paths. Absolute/relative path to the nuspec file
-InstallScriptPath string No Not recommended. Recommended using default Choco paths. Absolute/relative path to the ChocolateyInstall.ps1 script
-VerificationPath string No Not recommended. Recommended using default Choco paths. Absolute/relative path to the VERIFICATION.txt file
-FileDownloadTempPath string No **Not recommended. Recommended using default paths.**Absolute/relative path to save the file to
-FileDownloadTempPath64 string No **Not recommended. Recommended using default paths.**Absolute/relative path to save the file to

-ScrapeUrl64 and -ScrapePattern64 are not options because the version number should be the same regardless of architecture.

Script Parameters

If you add these two lines to the very top of your update.ps1 script, you can then use the -Debug or -Verbose parameters when calling the script and it will give you much more information about what it's doing.

[CmdletBinding()] # Enables -Debug parameter for troubleshooting
param ()
Screenshot of -Debug output

-Debug output

FAQ

  • Do I need to use the VERIFICATION.txt file?
    • No, it's optional unless you are distributing an EXE with the package (if EULA allows it). If you don't use it, just leave the parameter blank or comment it out.
  • Can I use ntfy.sh, Discord, Telegram, PagerDuty, Twilio, or some other service to alert me?
    • Not yet, unless you add it yourself. If you want to get it up and running, modify the SendAlertRaw function.
    • If you aren't sure what to change, ChatGPT is a good place to start.
    • ntfy is cool because once you get it setup, it integrates with many services. So in theory you could use ntfy to send a message to Discord, Telegram, PagerDuty, Twilio, and more.
    • I am working on adding native support for other services.
  • How much development is going into this?
    • I'm currently focused on multiple projects, but I'll definitely consider dedicating more time to this one based on community interest.
    • If you find it useful or promising, please click the Star button at the top right which serves as an indicator for me to continue its development.
    • Subscribe to release notifications by going to Watch → Custom → Releases → Apply
    • Thank you for your support!

To-Do List

  • Add UpdateSelf function
  • Add ntfy support to open up support for many other notification services (email, Discord, Telegram, PagerDuty, Twilio, etc.)
  • Add to PowerShell Gallery
  • Add script to Chocolatey community repository
  • Add more examples
  • Improve output/debug
  • Support alternate checksum/checksum64 specification in VERIFICATION.txt file (right now it expects checksum: and checksum64:)
  • Add check for missing nuspec
  • Add support for regex matches in case that is needed
  • Simplify the Usage section
  • Change it so that the UpdateChocolateyPackage function can be called without dot-sourcing the script (global function?)
  • Add color to output
  • Automatically remove previous nupkg file
  • Automatically push to Chocolatey community repository