Skip to content

Commit

Permalink
Versioning Strategy 3 (#1356)
Browse files Browse the repository at this point in the history
Setting versioning strategy to 3 will allow 3 segments of the version
number to be defined in app.json and repoVersion. Only the 4th segment
(Revision) will be defined by the GitHub
[run_number](https://go.microsoft.com/fwlink/?linkid=2217416&clcid=0x409)
for the CI/CD workflow. Increment version number and Create Release now
also supports the ability to set a third segment to the RepoVersion and
appversion in app.json.

Also, add support for skipping updating the dependency version numbers
in apps.

---------

Co-authored-by: freddydk <[email protected]>
  • Loading branch information
freddydk and freddydk authored Dec 18, 2024
1 parent 9eb6c9d commit c40b7c7
Show file tree
Hide file tree
Showing 15 changed files with 210 additions and 71 deletions.
11 changes: 9 additions & 2 deletions Actions/CalculateArtifactNames/CalculateArtifactNames.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,15 @@ if ($suffix) {
$suffix = "$suffix-$([DateTime]::UtcNow.ToString('yyyyMMdd'))"
}
else {
# Default suffix is the build number
$suffix = "$($settings.repoVersion).$($settings.appBuild).$($settings.appRevision)"
$repoVersion = [System.Version]$settings.repoVersion
$appBuild = $settings.appBuild
if ($appBuild -eq -1) {
$appBuild = $repoVersion.Build
if ($repoVersion.Build -eq -1) {
$appBuild = 0
}
}
$suffix = "$($repoVersion.Major).$($repoVersion.Minor).$($appBuild).$($settings.appRevision)"
}

'Apps', 'Dependencies', 'TestApps', 'TestResults', 'BcptTestResults', 'PageScriptingTestResults', 'PageScriptingTestResultDetails', 'BuildOutput', 'ContainerEventLog', 'PowerPlatformSolution' | ForEach-Object {
Expand Down
29 changes: 21 additions & 8 deletions Actions/IncrementVersionNumber/IncrementVersionNumber.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
[string] $token,
[Parameter(HelpMessage = "List of project names if the repository is setup for multiple projects (* for all projects)", Mandatory = $false)]
[string] $projects = '*',
[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)]
[Parameter(HelpMessage = "The version to update to. Use Major.Minor[.Build] for absolute change, use +1 to bump to the next major version, use +0.1 to bump to the next minor version or +0.0.1 to bump to the next build version", Mandatory = $true)]
[string] $versionNumber,
[Parameter(HelpMessage = "Skip updating dependency version numbers in all apps", Mandatory = $false)]
[bool] $skipUpdatingDependencies,
[Parameter(HelpMessage = "Set the branch to update", Mandatory = $false)]
[string] $updateBranch,
[Parameter(HelpMessage = "Direct commit?", Mandatory = $false)]
Expand All @@ -24,15 +26,24 @@ $settings = $env:Settings | ConvertFrom-Json
if ($versionNumber.StartsWith('+')) {
# Handle incremental version number
$allowedIncrementalVersionNumbers = @('+1', '+0.1')
if ($settings.versioningStrategy -eq 3) {
# Allow increment build
$allowedIncrementalVersionNumbers += '+0.0.1'
}
if (-not $allowedIncrementalVersionNumbers.Contains($versionNumber)) {
throw "Incremental version number $versionNumber is not allowed. Allowed incremental version numbers are: $($allowedIncrementalVersionNumbers -join ', ')"
}
}
else {
# Handle absolute version number
$versionNumberFormat = '^\d+\.\d+$' # Major.Minor
$correctFormatMsg = 'Major.Minor (e.g. 1.0 or 1.2)'
if ($settings.versioningStrategy -eq 3) {
$versionNumberFormat = '^\d+\.\d+\.\d+$' # Major.Minor.Build
$correctFormatMsg = 'Major.Minor.Build (e.g. 1.0, 1.2 or 1.2.3)'
}
if (-not ($versionNumber -match $versionNumberFormat)) {
throw "Version number $versionNumber is not in the correct format. The version number must be in the format Major.Minor (e.g. 1.0 or 1.2)"
throw "Version number $versionNumber is not in the correct format. The version number must be in the format $correctFormatMsg"
}
}

Expand Down Expand Up @@ -87,13 +98,15 @@ if ($projectList.Count -gt 0) {
$allAppFolders += $projectSettings.bcptTestFolders | ForEach-Object { Join-Path $projectPath $_ -Resolve }
}

# Set dependencies in app manifests
if ($allAppFolders.Count -eq 0) {
Write-Host "No App folders found for projects $projects"
}
else {
if (-not $skipUpdatingDependencies) {
# Set dependencies in app manifests
Set-DependenciesVersionInAppManifests -appFolders $allAppFolders
if ($allAppFolders.Count -eq 0) {
Write-Host "No App folders found for projects $projects"
}
else {
# Set dependencies in app manifests
Set-DependenciesVersionInAppManifests -appFolders $allAppFolders
}
}
}

Expand Down
45 changes: 32 additions & 13 deletions Actions/IncrementVersionNumber/IncrementVersionNumber.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
.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
New value of the setting. Allowed values are: +1 (increment major version number), +0.1 (increment minor version number), +0.0.1 (increment build version number) or a version number in the format Major.Minor (e.g. 1.0, 1.2 or (1.2.3)
.Parameter Force
If specified, the function will create the setting if it does not exist in the settings file.
#>
Expand Down Expand Up @@ -54,21 +54,22 @@ function Set-VersionInSettingsFile {
# Handle incremental version number

# Defensive check. Should never happen.
$allowedIncrementalVersionNumbers = @('+1', '+0.1')
$allowedIncrementalVersionNumbers = @('+1', '+0.1', '+0.0.1')
if (-not $allowedIncrementalVersionNumbers.Contains($newValue)) {
throw "Incremental version number $newValue is not allowed. Allowed incremental version numbers are: $($allowedIncrementalVersionNumbers -join ', ')"
throw "Unexpected error - incremental version number $newValue is not allowed. Allowed incremental version numbers are: $($allowedIncrementalVersionNumbers -join ', ')"
}
# Defensive check. Should never happen.
if($null -eq $oldVersion) {
throw "The setting $settingName does not exist in the settings file. It must exist to be able to increment the version number."
throw "Unexpected error - 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
# Defensive check. Should never happen.
$versionNumberFormat = '^\d+\.\d+(\.\d+)?$' # Major.Minor or Major.Minor.Build
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)"
throw "Unexpected error - version number $newValue is not in the correct format. The version number must be in the format Major.Minor or Major.Minor.Build (e.g. 1.0, 1.2 or 1.3.0)"
}
}
#endregion
Expand All @@ -80,25 +81,43 @@ function Set-VersionInSettingsFile {
# Increment major version number
$versionNumbers += $oldVersion.Major + 1
$versionNumbers += 0
# Include build number if it exists in the old version number
if ($oldVersion.Build -ne -1) {
$versionNumbers += 0
}
}
'+0.1' {
# Increment minor version number
$versionNumbers += $oldVersion.Major
$versionNumbers += $oldVersion.Minor + 1

# Include build number if it exists in the old version number
if ($oldVersion.Build -ne -1) {
$versionNumbers += 0
}
}
'+0.0.1' {
# Increment build version number
$versionNumbers += $oldVersion.Major
$versionNumbers += $oldVersion.Minor
if ($oldVersion.Build -eq -1) {
$versionNumbers += 1
}
else {
$versionNumbers += $oldVersion.Build + 1
}
}
default {
# Absolute version number
$versionNumbers += $newValue.Split('.')
if ($versionNumbers.Count -eq 2 -and ($null -ne $oldVersion -and $oldVersion.Build -ne -1)) {
$versionNumbers += 0
}
}
}

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

# Construct the new version number. Cast to System.Version to validate if the version number is valid.
Expand Down
1 change: 1 addition & 0 deletions Actions/IncrementVersionNumber/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Increment version number in AL-Go repository
| projects | | List of project names if the repository is setup for multiple projects (\* for all projects) | * |
| 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 |
| skipUpdatingDependencies | | Skip updating dependency version numbers in all apps | false |
| directCommit | | true if the action should create a direct commit against the branch or false to create a Pull Request | false |

## OUTPUT
Expand Down
9 changes: 7 additions & 2 deletions Actions/IncrementVersionNumber/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@ inputs:
required: false
default: '*'
versionNumber:
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
description: The version to update to. Use Major.Minor[.Build] for absolute change, use +1 to bump to the next major version, use +0.1 to bump to the next minor version or +0.0.1 to bump to the next build version
required: true
skipUpdatingDependencies:
description: Skip updating dependency version numbers in all apps
required: false
default: 'false'
updateBranch:
description: Set the branch to update
required: false
Expand All @@ -41,11 +45,12 @@ runs:
_token: ${{ inputs.token }}
_projects: ${{ inputs.projects }}
_versionNumber: ${{ inputs.versionNumber }}
_skipUpdatingDependencies: ${{ inputs.skipUpdatingDependencies }}
_updateBranch: ${{ inputs.updateBranch }}
_directCommit: ${{ inputs.directCommit }}
run: |
${{ github.action_path }}/../Invoke-AlGoAction.ps1 -ActionName "IncrementVersionNumber" -Action {
${{ github.action_path }}/IncrementVersionNumber.ps1 -actor $ENV:_actor -token $ENV:_token -projects $ENV:_projects -versionNumber $ENV:_versionNumber -updateBranch $ENV:_updateBranch -directCommit ($ENV:_directCommit -eq 'true')
${{ github.action_path }}/IncrementVersionNumber.ps1 -actor $ENV:_actor -token $ENV:_token -projects $ENV:_projects -versionNumber $ENV:_versionNumber -skipUpdatingDependencies ($ENV:_skipUpdatingDependencies -eq 'true') -updateBranch $ENV:_updateBranch -directCommit ($ENV:_directCommit -eq 'true')
}
branding:
icon: terminal
Expand Down
4 changes: 4 additions & 0 deletions Actions/ReadSettings/ReadSettings.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ if ($settings.versioningstrategy -ne -1) {
$settings.appBuild = [Int32]([DateTime]::UtcNow.ToString('yyyyMMdd'))
$settings.appRevision = [Int32]([DateTime]::UtcNow.ToString('HHmmss'))
}
3 { # USE BUIlD from app.json and RUN_NUMBER
$settings.appBuild = -1
$settings.appRevision = $settings.runNumberOffset + [Int32]($ENV:GITHUB_RUN_NUMBER)
}
15 { # Use maxValue
$settings.appBuild = [Int32]::MaxValue
$settings.appRevision = 0
Expand Down
8 changes: 8 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
### Issues

- It is now possible to skip the modification of dependency version numbers when running the Increment Version number workflow or the Create Release workflow

### New Versioning Strategy

Setting versioning strategy to 3 will allow 3 segments of the version number to be defined in app.json and repoVersion. Only the 4th segment (Revision) will be defined by the GitHub [run_number](https://go.microsoft.com/fwlink/?linkid=2217416&clcid=0x409) for the CI/CD workflow. Increment version number and Create Release now also supports the ability to set a third segment to the RepoVersion and appversion in app.json.

## v6.2

### Issues
Expand Down
2 changes: 1 addition & 1 deletion Scenarios/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ The repository settings are only read from the repository settings file (.github
| <a id="updateDependencies"></a>updateDependencies | Setting updateDependencies to true causes AL-Go to build your app against the first compatible Business Central build and set the dependency version numbers in the app.json accordingly during build. All version numbers in the built app will be set to the version number used during compilation. | false |
| <a id="generateDependencyArtifact"></a>generateDependencyArtifact | When this repository setting is true, CI/CD pipeline generates an artifact with the external dependencies used for building the apps in this repo. | false |
| <a id="companyName"></a>companyName | Company name selected in the database, used for running the CI/CD workflow. Default is to use the default company in the selected Business Central localization. | |
| <a id="versioningStrategy"></a>versioningStrategy | The versioning strategy determines how versioning is performed in this project. The version number of an app consists of 4 tuples: **Major**.**Minor**.**Build**.**Revision**. **Major** and **Minor** are read from the app.json file for each app. **Build** and **Revision** are calculated. Currently 3 versioning strategies are supported:<br />**0** = **Build** is the **github [run_number](https://go.microsoft.com/fwlink/?linkid=2217416&clcid=0x409)** for the CI/CD workflow, increased by the **runNumberOffset** setting value (if specified). **Revision** is the **github [run_attempt](https://go.microsoft.com/fwlink/?linkid=2217416&clcid=0x409)** subtracted 1.<br />**2** = **Build** is the current date as **yyyyMMdd**. **Revision** is the current time as **hhmmss**. Date and time are always **UTC** timezone to avoid problems during daylight savings time change. Note that if two CI/CD workflows are started within the same second, this could yield to identical version numbers from two different runs.<br />**+16** use **repoVersion** setting as **appVersion** (**Major** and **Minor**) for all apps | 0 |
| <a id="versioningStrategy"></a>versioningStrategy | The versioning strategy determines how versioning is performed in this project. The version number of an app consists of 4 segments: **Major**.**Minor**.**Build**.**Revision**. **Major** and **Minor** are read from the app.json file for each app. **Build** and **Revision** are calculated. Currently 3 versioning strategies are supported:<br />**0** = **Build** is the **github [run_number](https://go.microsoft.com/fwlink/?linkid=2217416&clcid=0x409)** for the CI/CD workflow, increased by the **runNumberOffset** setting value (if specified). **Revision** is the **github [run_attempt](https://go.microsoft.com/fwlink/?linkid=2217416&clcid=0x409)** subtracted 1.<br />**2** = **Build** is the current date as **yyyyMMdd**. **Revision** is the current time as **hhmmss**. Date and time are always **UTC** timezone to avoid problems during daylight savings time change. Note that if two CI/CD workflows are started within the same second, this could yield to identical version numbers from two different runs.<br />**3** = **Build** is taken from **app.json** (like Major and Minor) and **Revision** is the **github [run_number](https://go.microsoft.com/fwlink/?linkid=2217416&clcid=0x409)** for the CI/CD workflow<br />**+16** use **repoVersion** setting as **appVersion** for all apps | 0 |
| <a id="additionalCountries"></a>additionalCountries | This property can be set to an additional number of countries to compile, publish and test your app against during workflows. Note that this setting can be different in NextMajor and NextMinor workflows compared to the CI/CD workflow, by specifying a different value in a workflow settings file. | \[ \] |
| <a id="keyVaultName"></a>keyVaultName | When using Azure KeyVault for the secrets used in your workflows, the KeyVault name needs to be specified in this setting if it isn't specified in the AZURE_CREDENTIALS secret. Read [this](UseAzureKeyVault.md) for more information. | |
| <a id="licenseFileUrlSecretName"></a>licenseFileUrlSecretName | Specify the name (**NOT the secret**) of the LicenseFileUrl secret. Default is LicenseFileUrl. AL-Go for GitHub will look for a secret with this name in GitHub Secrets or Azure KeyVault to use as LicenseFileUrl. A LicenseFileUrl is required when building AppSource apps for Business Central prior to version 22. Read [this](SetupCiCdForExistingAppSourceApp.md) for more information. | LicenseFileUrl |
Expand Down
29 changes: 17 additions & 12 deletions Templates/AppSource App/.github/workflows/CreateRelease.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ on:
description: Tag of this release (needs to be semantic version string https://semver.org, ex. 1.0.0)
required: true
default: ''
prerelease:
description: Prerelease?
type: boolean
default: false
draft:
description: Draft?
type: boolean
default: false
releaseType:
description: Release, prerelease or draft?
type: choice
options:
- Release
- Prerelease
- Draft
default: Release
createReleaseBranch:
description: Create Release Branch?
type: boolean
Expand All @@ -33,9 +33,13 @@ on:
type: string
default: release/
updateVersionNumber:
description: New Version Number in main branch. Use Major.Minor for absolute change, use +Major.Minor for incremental change.
description: New Version Number in main branch. Use Major.Minor (optionally add .Build for versioningstrategy 3) for absolute change, or +1, +0.1 (or +0.0.1 for versioningstrategy 3) incremental change.
required: false
default: ''
skipUpdatingDependencies:
description: Skip updating dependency version numbers in all apps.
type: boolean
default: false
directCommit:
description: Direct Commit?
type: boolean
Expand Down Expand Up @@ -183,7 +187,7 @@ jobs:
$sha = $artifact.workflow_run.head_sha
}
write-host "looking for $project-$refname-Apps-$artifactsVersion or $project-$refname-TestApps-$artifactsVersion or $project-$refname-Dependencies-$artifactsVersion or $project-$refname-PowerPlatformSolution-$artifactsVersion"
Write-host "Looking for $project-$refname-Apps-$artifactsVersion or $project-$refname-TestApps-$artifactsVersion or $project-$refname-Dependencies-$artifactsVersion or $project-$refname-PowerPlatformSolution-$artifactsVersion"
$allArtifacts | Where-Object { ($_.name -like "$project-$refname-Apps-$artifactsVersion" -or $_.name -like "$project-$refname-TestApps-$artifactsVersion" -or $_.name -like "$project-$refname-Dependencies-$artifactsVersion" -or $_.name -like "$project-$refname-PowerPlatformSolution-$artifactsVersion") } | ForEach-Object {
$atype = $_.name.SubString(0,$_.name.Length-$artifactsVersion.Length-1)
$atype = $atype.SubString($atype.LastIndexOf('-')+1)
Expand Down Expand Up @@ -224,8 +228,8 @@ jobs:
tag_name: '${{ github.event.inputs.tag }}',
name: '${{ github.event.inputs.name }}',
body: bodyMD.replaceAll('\\n','\n').replaceAll('%0A','\n').replaceAll('%0D','\n').replaceAll('%25','%'),
draft: ${{ github.event.inputs.draft=='true' }},
prerelease: ${{ github.event.inputs.prerelease=='true' }},
draft: ${{ github.event.inputs.releaseType=='Draft' }},
prerelease: ${{ github.event.inputs.releaseType=='Prerelease' }},
make_latest: 'legacy',
target_commitish: '${{ steps.analyzeartifacts.outputs.commitish }}'
});
Expand Down Expand Up @@ -365,6 +369,7 @@ jobs:
shell: powershell
token: ${{ steps.ReadSecrets.outputs.TokenForPush }}
versionNumber: ${{ github.event.inputs.updateVersionNumber }}
skipUpdatingDependencies: ${{ github.event.inputs.skipUpdatingDependencies }}
directCommit: ${{ github.event.inputs.directCommit }}

PostProcess:
Expand Down
Loading

0 comments on commit c40b7c7

Please sign in to comment.