Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve IncrementVersionNumber action #910

Merged
merged 35 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
d27df11
Validate version number
mazhelez Jan 24, 2024
736252e
Fix increment version logic to work with wild cards in appFolders and…
mazhelez Jan 30, 2024
7eef2a8
Better naming + doc
mazhelez Jan 30, 2024
9c821bb
Rename value
mazhelez Jan 30, 2024
7d5dbf6
Fix var name
mazhelez Jan 30, 2024
bac2fa4
Add tests for Set-SettingInFile
mazhelez Jan 30, 2024
f0ab04d
Make Set-ProjectVersion work with projectSettings
mazhelez Jan 31, 2024
195b5f4
Merge branch 'main' into fix-CreateRelease
mazhelez Jan 31, 2024
cfdda55
Refactor to re-use Set-SettingInFile
mazhelez Jan 31, 2024
b6dee6d
Fix newVersion reference
mazhelez Jan 31, 2024
34aa16b
Clean-up, add comments, etc.
mazhelez Jan 31, 2024
0a57bad
Merge branch 'fix-CreateRelease' of https://github.com/mazhelez/AL-Go…
mazhelez Jan 31, 2024
c5e21e8
Fix parameter name
mazhelez Jan 31, 2024
fdd6c32
Improve version changing functionality
mazhelez Feb 1, 2024
4f038c9
Move "incremental" logic in Set-VersionSettingInFile
mazhelez Feb 1, 2024
7a0ac95
Add/improve tests
mazhelez Feb 1, 2024
df513c8
Add some code comments
mazhelez Feb 1, 2024
0e50768
Clean up doc
mazhelez Feb 1, 2024
cfad51e
Add release notes
mazhelez Feb 1, 2024
4e1e67a
Pass ALGOsettingsFile as param
mazhelez Feb 1, 2024
55a5d58
Set version property in the dependencies array in the app.json
mazhelez Feb 5, 2024
5ed6470
Change design of incrementing version:
mazhelez Feb 8, 2024
d367b95
Set dependencies version in app manifest files (app.json)
mazhelez Feb 8, 2024
b20a6cd
Add doc for Set-DependenciesVersionInAppManifests
mazhelez Feb 8, 2024
3f885fd
Remove ValueFromPipeline (unused anyway)
mazhelez Feb 8, 2024
5138ce8
Remove version validation (it's validated when set)
mazhelez Feb 8, 2024
b7ee172
Fix var ref
mazhelez Feb 8, 2024
6237577
Fix versionNumber doc
mazhelez Feb 8, 2024
df2a6c7
Fix versionNumber doc (2)
mazhelez Feb 8, 2024
cc05a3a
Fix param refernce
mazhelez Feb 8, 2024
abbfa8d
Use -Encoding UTF8 when reading JSON files
mazhelez Feb 9, 2024
8770682
Use Set-JsonContentLF
mazhelez Feb 9, 2024
1441efb
Add logs
mazhelez Feb 9, 2024
1dba93d
Add docs
mazhelez Feb 9, 2024
78bba82
Ensure repoVersion is set in the repo settings.
mazhelez Feb 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 39 additions & 75 deletions Actions/IncrementVersionNumber/IncrementVersionNumber.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
[string] $parentTelemetryScopeJson = '7b7d',
[Parameter(HelpMessage = "List of project names if the repository is setup for multiple projects (* for all projects)", Mandatory = $false)]
[string] $projects = '*',
[Parameter(HelpMessage = "Updated Version Number. Use Major.Minor for absolute change, use +Major.Minor for incremental change.", Mandatory = $true)]
[Parameter(HelpMessage = "The version to update to. Use Major.Minor for absolute change, use +1 to bump to the next major version, use +0.1 to bump to the next minor version", Mandatory = $true)]
[string] $versionNumber,
[Parameter(HelpMessage = "Set the branch to update", Mandatory = $false)]
[string] $updateBranch,
Expand All @@ -19,92 +19,56 @@ $telemetryScope = $null

try {
. (Join-Path -Path $PSScriptRoot -ChildPath "..\AL-Go-Helper.ps1" -Resolve)
Import-Module (Join-Path -path $PSScriptRoot -ChildPath "IncrementVersionNumber.psm1" -Resolve)

$serverUrl, $branch = CloneIntoNewFolder -actor $actor -token $token -updateBranch $updateBranch -DirectCommit $directCommit -newBranchPrefix 'increment-version-number'
$baseFolder = (Get-Location).path
DownloadAndImportBcContainerHelper -baseFolder $baseFolder

import-module (Join-Path -path $PSScriptRoot -ChildPath "..\TelemetryHelper.psm1" -Resolve)
Import-Module (Join-Path -path $PSScriptRoot -ChildPath "..\TelemetryHelper.psm1" -Resolve)
$telemetryScope = CreateScope -eventId 'DO0076' -parentTelemetryScopeJson $parentTelemetryScopeJson

$addToVersionNumber = "$versionNumber".StartsWith('+')
if ($addToVersionNumber) {
$versionNumber = $versionNumber.Substring(1)
}
try {
$newVersion = [System.Version]"$($versionNumber).0.0"
}
catch {
throw "Version number ($versionNumber) is malformed. A version number must be structured as <Major>.<Minor> or +<Major>.<Minor>"
}

$settings = $env:Settings | ConvertFrom-Json

# Ensure the repoVersion setting exists in the repository settings. Defaults to 1.0 if it doesn't exist.
Set-VersionInSettingsFile -settingsFilePath (Join-Path $baseFolder $RepoSettingsFile) -settingName 'repoVersion' -newValue $settings.repoVersion -Force # $RepoSettingsFile is defined in AL-Go-Helper.ps1

# Change repoVersion in repository settings
Set-VersionInSettingsFile -settingsFilePath (Join-Path $baseFolder $RepoSettingsFile) -settingName 'repoVersion' -newValue $versionNumber

$projectList = @(GetProjectsFromRepository -baseFolder $baseFolder -projectsFromSettings $settings.projects -selectProjects $projects)

$allAppFolders = @()
foreach($project in $projectList) {
try {
Write-Host "Reading settings from $project\$ALGoSettingsFile"
$settingsJson = Get-Content "$project\$ALGoSettingsFile" -Encoding UTF8 | ConvertFrom-Json
if ($settingsJson.PSObject.Properties.Name -eq "repoVersion") {
$oldVersion = [System.Version]"$($settingsJson.repoVersion).0.0"
if ((!$addToVersionNumber) -and $newVersion -le $oldVersion) {
throw "The new version number ($($newVersion.Major).$($newVersion.Minor)) must be larger than the old version number ($($oldVersion.Major).$($oldVersion.Minor))"
}
$repoVersion = $newVersion
if ($addToVersionNumber) {
$repoVersion = [System.Version]"$($newVersion.Major+$oldVersion.Major).$($newVersion.Minor+$oldVersion.Minor).0.0"
}
$settingsJson.repoVersion = "$($repoVersion.Major).$($repoVersion.Minor)"
}
else {
$repoVersion = $newVersion
if ($addToVersionNumber) {
$repoVersion = [System.Version]"$($newVersion.Major+1).$($newVersion.Minor).0.0"
}
Add-Member -InputObject $settingsJson -NotePropertyName "repoVersion" -NotePropertyValue "$($repoVersion.Major).$($repoVersion.Minor)" | Out-Null
}
$useRepoVersion = (($settingsJson.PSObject.Properties.Name -eq "versioningStrategy") -and (($settingsJson.versioningStrategy -band 16) -eq 16))
$settingsJson
$settingsJson | Set-JsonContentLF -path "$project\$ALGoSettingsFile"
}
catch {
throw "Settings file $project\$ALGoSettingsFile is malformed.$([environment]::Newline) $($_.Exception.Message)."
}

$folders = @('appFolders', 'testFolders' | ForEach-Object { if ($SettingsJson.PSObject.Properties.Name -eq $_) { $settingsJson."$_" } })
if (-not ($folders)) {
$folders = Get-ChildItem -Path $project | Where-Object { $_.PSIsContainer -and (Test-Path (Join-Path $_.FullName 'app.json')) } | ForEach-Object { $_.Name }
}
$folders | ForEach-Object {
Write-Host "Modifying app.json in folder $project\$_"
$appJsonFile = Join-Path "$project\$_" "app.json"
if (Test-Path $appJsonFile) {
try {
$appJson = Get-Content $appJsonFile -Encoding UTF8 | ConvertFrom-Json
$oldVersion = [System.Version]$appJson.Version
if ($useRepoVersion) {
$appVersion = $repoVersion
}
elseif ($addToVersionNumber) {
$appVersion = [System.Version]"$($newVersion.Major+$oldVersion.Major).$($newVersion.Minor+$oldVersion.Minor).0.0"
}
else {
$appVersion = $newVersion
}
$appJson.Version = "$appVersion"
$appJson | Set-JsonContentLF -path $appJsonFile
}
catch {
throw "Application manifest file($appJsonFile) is malformed."
}
}
}
}
if ($addToVersionNumber) {
CommitFromNewFolder -serverUrl $serverUrl -commitMessage "Increment Version number by $($newVersion.Major).$($newVersion.Minor)" -branch $branch | Out-Null
$projectPath = Join-Path $baseFolder $project

# Set repoVersion in project settings (if it exists)
$projectSettingsPath = Join-Path $projectPath $ALGoSettingsFile # $ALGoSettingsFile is defined in AL-Go-Helper.ps1
Set-VersionInSettingsFile -settingsFilePath $projectSettingsPath -settingName 'repoVersion' -newValue $versionNumber

# Resolve project folders to get all app folders that contain an app.json file
$projectSettings = ReadSettings -baseFolder $baseFolder -project $project
ResolveProjectFolders -baseFolder $baseFolder -project $project -projectSettings ([ref] $projectSettings)

# Set version in app manifests (app.json files)
Set-VersionInAppManifests -projectPath $projectPath -projectSettings $projectSettings -newValue $versionNumber

# Collect all project's app folders
$allAppFolders += $projectSettings.appFolders | ForEach-Object { Join-Path $projectPath $_ -Resolve }
$allAppFolders += $projectSettings.testFolders | ForEach-Object { Join-Path $projectPath $_ -Resolve }
$allAppFolders += $projectSettings.bcptTestFolders | ForEach-Object { Join-Path $projectPath $_ -Resolve }
}
else {
CommitFromNewFolder -serverUrl $serverUrl -commitMessage "New Version number $($newVersion.Major).$($newVersion.Minor)" -branch $branch | Out-Null

# Set dependencies in app manifests
Set-DependenciesVersionInAppManifests -appFolders $allAppFolders

$commitMessage = "New Version number $versionNumber"
if ($versionNumber.StartsWith('+')) {
$commitMessage = "Incremented Version number by $versionNumber"
}

CommitFromNewFolder -serverUrl $serverUrl -commitMessage $commitMessage -branch $branch | Out-Null

TrackTrace -telemetryScope $telemetryScope
}
catch {
Expand Down
200 changes: 200 additions & 0 deletions Actions/IncrementVersionNumber/IncrementVersionNumber.psm1
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
<#
.Synopsis
Changes a version setting value in a settings file.
.Description
Changes a version setting value in a settings file.
If the setting does not exist in the settings file, the function does nothing, unless the Force parameter is specified.
.Parameter settingsFilePath
Path to a JSON file containing the settings.
.Parameter settingName
Name of the setting to change. The setting must be a version number.
.Parameter newValue
New value of the setting. Allowed values are: +1 (increment major version number), +0.1 (increment minor version number), or a version number in the format Major.Minor (e.g. 1.0 or 1.2
.Parameter Force
If specified, the function will create the setting if it does not exist in the settings file.
#>
function Set-VersionInSettingsFile {
mazhelez marked this conversation as resolved.
Show resolved Hide resolved
param(
[Parameter(Mandatory = $true)]
[string] $settingsFilePath,
Fixed Show fixed Hide fixed
[Parameter(Mandatory = $true)]
[string] $settingName,
[Parameter(Mandatory = $true)]
[string] $newValue,
[switch] $Force
)

#region Validate parameters
if (-not (Test-Path $settingsFilePath)) {
throw "Settings file ($settingsFilePath) not found."
}

Write-Host "Reading settings from $settingsFilePath"
try {
$settingsJson = Get-Content $settingsFilePath -Encoding UTF8 -Raw | ConvertFrom-Json
}
catch {
throw "Settings file ($settingsFilePath) is malformed: $_"
}

$settingExists = [bool] ($settingsJson.PSObject.Properties.Name -eq $settingName)
if ((-not $settingExists) -and (-not $Force)) {
Write-Host "Setting $settingName not found in $settingsFilePath"
return
}

# Add the setting if it does not exist
if (-not $settingExists) {
$settingsJson | Add-Member -MemberType NoteProperty -Name $settingName -Value $null
}

$oldValue = [System.Version] $settingsJson.$settingName
# Validate new version value
if ($newValue.StartsWith('+')) {
# Handle incremental version number

$allowedIncrementalVersionNumbers = @('+1', '+0.1')
if (-not $allowedIncrementalVersionNumbers.Contains($newValue)) {
throw "Incremental version number $newValue is not allowed. Allowed incremental version numbers are: $($allowedIncrementalVersionNumbers -join ', ')"
}

# Defensive check. Should never happen.
if($null -eq $oldValue) {
throw "The setting $settingName does not exist in the settings file. It must exist to be able to increment the version number."
}
}
else {
# Handle absolute version number

$versionNumberFormat = '^\d+\.\d+$' # Major.Minor
if (-not ($newValue -match $versionNumberFormat)) {
throw "Version number $newValue is not in the correct format. The version number must be in the format Major.Minor (e.g. 1.0 or 1.2)"
}
}
#endregion

$versionNumbers = @() # an array to hold the version numbers: major, minor, build, revision

switch($newValue) {
'+1' {
# Increment major version number
$versionNumbers += $oldValue.Major + 1
$versionNumbers += 0
}
'+0.1' {
# Increment minor version number
$versionNumbers += $oldValue.Major
$versionNumbers += $oldValue.Minor + 1

}
default {
# Absolute version number
$versionNumbers += $newValue.Split('.')
}
}

# Include build and revision numbers if they exist in the old version number
if ($oldValue -and ($oldValue.Build -ne -1)) {
$versionNumbers += $oldValue.Build
if ($oldValue.Revision -ne -1) {
$versionNumbers += $oldValue.Revision
}
}

# Construct the new version number. Cast to System.Version to validate if the version number is valid.
$newValue = [System.Version] "$($versionNumbers -join '.')"

if($newValue -eq $oldValue) {
Write-Host "The setting $settingName is already set to $newValue in $settingsFilePath"
return
}

if($null -eq $oldValue) {
Write-Host "Setting setting $settingName to $newValue in $settingsFilePath"
}
else {
Write-Host "Changing $settingName from $oldValue to $newValue in $settingsFilePath"
}

$settingsJson.$settingName = $newValue.ToString()
$settingsJson | Set-JsonContentLF -Path $settingsFilePath
}

<#
.Synopsis
Changes the version number of a project.
.Description
Changes the version number of a project.
The version number is changed in the project settings file (value for 'repoVersion') and in the app.json files of all apps in the project, as well as all references to the apps in the dependencies of the app.json files.
.Parameter baseFolder
Base folder of the repository.
.Parameter project
Name of the project (relative to the base folder).
.Parameter newValue
New version number. If the version number starts with a +, the new version number will be added to the old version number. Else the new version number will replace the old version number.
#>
function Set-VersionInAppManifests($projectPath, $projectSettings, $newValue) {

# Check if the project uses repoVersion versioning strategy
$useRepoVersion = (($projectSettings.PSObject.Properties.Name -eq "versioningStrategy") -and (($projectSettings.versioningStrategy -band 16) -eq 16))
if ($useRepoVersion) {
$newValue = $projectSettings.repoVersion
}

$allAppFolders = @($projectSettings.appFolders) + @($projectSettings.testFolders) + @($projectSettings.bcptTestFolders)
# Set version in app.json files
$allAppFolders | ForEach-Object {
$appFolder = Join-Path $projectPath $_
$appJson = Join-Path $appFolder "app.json"

Set-VersionInSettingsFile -settingsFilePath $appJson -settingName 'version' -newValue $newValue
}
}

<#
.Synopsis
Changes the version number of dependencies in app.json files.
.Description
Changes the version number of dependencies in app.json files.
The version number of the dependencies is changed to the version number of the app that the dependency refers to. If the app is not found, the version number of the dependency is not changed.
.Parameter appFolders
Array of paths to the app folders. Each app folder must contain an app.json file. The apps are used to get the version number of the dependencies.
#>
function Set-DependenciesVersionInAppManifests {
Fixed Show fixed Hide fixed
param(
[Parameter(Mandatory = $true)]
[string[]] $appFolders
)

# Get all apps info: app ID and app version
$appsInfos = @($appFolders | ForEach-Object {
$appJson = Join-Path $_ "app.json"
$app = Get-Content -Path $appJson -Encoding UTF8 -Raw | ConvertFrom-Json
return [PSCustomObject]@{
Id = $app.id
Version = $app.version
}
})

# Update dependencies in app.json files
$appFolders | ForEach-Object {
$appJsonPath = Join-Path $_ "app.json"

$appJson = Get-Content -Path $appJsonPath -Encoding UTF8 -Raw | ConvertFrom-Json

$dependencies = $appJson.dependencies

$dependencies | ForEach-Object {
$dependency = $_
$appInfo = $appsInfos | Where-Object { $_.Id -eq $dependency.id }
if ($appInfo) {
Write-Host "Updating dependency app $($dependency.id) in $appJsonPath from $($dependency.version) to $($appInfo.Version)"
$dependency.version = $appInfo.Version
}
}

$appJson | Set-JsonContentLF -Path $appJsonPath
}
}

Export-ModuleMember -Function Set-VersionInSettingsFile, Set-VersionInAppManifests, Set-DependenciesVersionInAppManifests
2 changes: 1 addition & 1 deletion Actions/IncrementVersionNumber/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Increment version number in AL-Go repository
| token | | The GitHub token running the action | github.token |
| parentTelemetryScopeJson | | Specifies the parent telemetry scope for the telemetry signal | {} |
| projects | | List of project names if the repository is setup for multiple projects (* for all projects) | * |
| versionNumber | Yes | Updated Version Number. Use Major.Minor for absolute change, use +Major.Minor for incremental change | |
| versionNumber | Yes | The version to update to. Use Major.Minor for absolute change, use +1 to bump to the next major version, use +0.1 to bump to the next minor version | |
| updateBranch | | Which branch should the app be added to | github.ref_name |
| directCommit | | true if the action should create a direct commit against the branch or false to create a Pull Request | false |

Expand Down
2 changes: 1 addition & 1 deletion Actions/IncrementVersionNumber/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ inputs:
required: false
default: '*'
versionNumber:
description: Updated Version Number. Use Major.Minor for absolute change, use +Major.Minor for incremental change.
description: The version to update to. Use Major.Minor for absolute change, use +1 to bump to the next major version, use +0.1 to bump to the next minor version
required: true
updateBranch:
description: Set the branch to update
Expand Down
7 changes: 4 additions & 3 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ Note that when using the preview version of AL-Go for GitHub, we recommend you U
### Issues
- Support release branches that start with releases/
- Issue 870 Improve Error Handling when CLI is missing
- Issue 889 CreateRelease and IncrementVersionNumber workflow did not handle wild characters in `appFolders`, `testFolders` or `bcptTestFolders` settings.

### Build modes
AL-Go ships with Default, Translated and Clean mode out of the box. Now you can also define custom build modes in addition to the ones shipped with AL-Go. This allows you to define your own build modes, which can be used to build your apps in different ways. By default, a custom build mode will build the apps similarly to the Default mode but this behavior can be overridden in e.g. script overrides in your repository.
### Build modes
AL-Go ships with Default, Translated and Clean mode out of the box. Now you can also define custom build modes in addition to the ones shipped with AL-Go. This allows you to define your own build modes, which can be used to build your apps in different ways. By default, a custom build mode will build the apps similarly to the Default mode but this behavior can be overridden in e.g. script overrides in your repository.

## v4.1

Expand Down Expand Up @@ -45,7 +46,7 @@ If false, the templateSha repository setting is used to download specific AL-Go
- **footer** = Footer for the documentation site. (Default: Made with...)
- **defaultIndexMD** = Markdown for the landing page of the documentation site. (Default: Reference documentation...)
- **defaultReleaseMD** = Markdown for the landing page of the release sites. (Default: Release reference documentation...)
- *Note that in header, footer, defaultIndexMD and defaultReleaseMD you can use the following placeholders: {REPOSITORY}, {VERSION}, {INDEXTEMPLATERELATIVEPATH}, {RELEASENOTES}*
- *Note that in header, footer, defaultIndexMD and defaultReleaseMD you can use the following placeholders: {REPOSITORY}, {VERSION}, {INDEXTEMPLATERELATIVEPATH}, {RELEASENOTES}*

### New Workflows
- **Deploy Reference Documentation** is a workflow, which you can invoke manually or on a schedule to generate and deploy reference documentation using the aldoc tool, using the ALDoc setting properties described above.
Expand Down
Loading
Loading