diff --git a/.github/workflows/BuildNewCommits.yml b/.github/workflows/BuildNewCommits.yml new file mode 100644 index 00000000000..b87aa61cce2 --- /dev/null +++ b/.github/workflows/BuildNewCommits.yml @@ -0,0 +1,57 @@ +name: BuildNewCommits + +on: + schedule: + - cron: '0 0 * * *' + workflow_dispatch: + +jobs: + prepare: + name: Prepare Matrix + runs-on: ubuntu-latest + + outputs: + countries: ${{ steps.load_countries.outputs.countries }} + + steps: + - name: Install BC Container Helper + shell: pwsh + run: Install-Module bccontainerhelper -force + + - name: Check out the repository to the runner + uses: actions/checkout@v4.1.2 + with: + ref: master + + - name: Load Countries + id: load_countries + shell: pwsh + run: ./scripts/GetAllCountries.ps1 + + - name: ShowOutput + shell: pwsh + run: Write-Host '${{ steps.load_countries.outputs.countries }}' + + buildCommits: + needs: prepare + name: Build Commits + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.prepare.outputs.countries) }} + + steps: + - name: Install BC Container Helper + shell: pwsh + run: Install-Module bccontainerhelper -force + + - name: Check out the repository to the runner + uses: actions/checkout@v4.1.2 + + - name: Build Commits + shell: pwsh + run: | + ./scripts/Auto_load_versions.ps1 -country ${{matrix.countries}} + + diff --git a/Misc-apps.code-workspace b/Misc-apps.code-workspace deleted file mode 100644 index 414de46067b..00000000000 --- a/Misc-apps.code-workspace +++ /dev/null @@ -1,80 +0,0 @@ -{ - "folders": [ - { - "name": "API V1 App", - "path": "APIV1/source" - }, - { - "name": "API V1 Tests", - "path": "APIV1/test" - }, - { - "name": "API V2 App", - "path": "APIV2/source" - }, - { - "name": "API V2 Tests", - "path": "APIV2/test" - }, - { - "name": "Client AddIns", - "path": "ClientAddIns/source" - }, - { - "name": "Company Hub", - "path": "CompanyHub/source" - }, - { - "name": "Headlines App", - "path": "EssentialBusinessHeadlines/source" - }, - { - "name": "Headlines Tests", - "path": "EssentialBusinessHeadlines/test" - }, - { - "name": "Late Payment Predictor App", - "path": "LatePaymentPredictor/source" - }, - { - "name": "Late Payment Predictor Tests", - "path": "LatePaymentPredictor/test" - }, - { - "name": "PayPal App", - "path": "paypalpaymentsstandard/source" - }, - { - "name": "PayPal Tests", - "path": "paypalpaymentsstandard/test" - }, - { - "name": "Sales/Inventory Forecast App", - "path": "salesandinventoryforecast/source" - }, - { - "name": "Sales/Inventory Forecast Tests", - "path": "salesandinventoryforecast/test" - }, - { - "name": "Send to Email Printer", - "path": "sendtoemailprinter/source" - }, - { - "name": "UK send remittance advice", - "path": "uksendremittanceadvice/source" - }, - { - "name": "Test Framework", - "path": "TestFramework" - }, - ], - "settings": { - "allint.enabled": false, - "al.enableCodeActions": false, - "al.enableCodeAnalysis": false, - "search.exclude": { - "**.xlf": true - } - } -} \ No newline at end of file diff --git a/README.md b/README.md index daaa6a787e8..8680627cc46 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,95 @@ This repository holds all versions of the Buisness Central Apps. The purpose is There is one separate branch per country-major version. +Go the one of the `w1` branches to find most of the code: +https://github.com/StefanMaron/MSDyn365BC.Code.History/branches/all?query=w1 + +Check out the country specific branches to view the localized base app. For example `DE`: +https://github.com/StefanMaron/MSDyn365BC.Code.History/branches/all?query=de + +## Schedule + +The repository will automatically update itself from the artifacts once a day: + +- Regular/current branches will run at midnight UTC and pull the last 24 hours of artifacts +- vNext/insider branches will run at 2 am UTC and pull the last 24 hours of artifacts + +## Differences + +Main differences between the https://github.com/StefanMaron/MSDyn365BC.Code.History repo: +- Builds on sandbox instead of OnPrem artifacts to include hotfixes +- localization branches only include the localized code, so some of them are empty, some just have the base app (Check w1 branches for all the other code) +- the commits are added by pipelines to reduce runtime +- the pipelines will be scheduled to run daily once the initial load is done. +- there will be branches to cover NextMajor/Minor as well (Look out for suffix vNext in the branches) +- the main branch is just holding the scripts, switch branch to see the BC Code +- Because of the crazy number of versions, I did limit this repo to start with 23.5 +- to keep the size of this repo at least in some boundaries, I decided to not include any translation files. + +## Partial Clone (Subset of Branches) +To reduce the size of the local clone you can use those commands to clone only the branches you need: + +First, clone with those parameters and set it to whatever branch you need: +``` +git clone -b w1-24 --single-branch https://github.com/StefanMaron/MSDyn365BC.Code.History +``` +if you want to add additional branches you can do it like this +``` +git remote set-branches --add origin de-24 +git remote set-branches --add origin de-23 +git fetch +``` +You can also use wildcards for [remote-branch], e.g. +``` +git remote set-branches --add origin us-* +git fetch +``` + +Removing tracking branches is a little more complicated. +First you need to manually edit the `.git/config` file and remove the branches in the `[remote "origin"]` section +``` +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true +[remote "origin"] + url = https://github.com/StefanMaron/MSDyn365BC.Code.History + fetch = +refs/heads/w1-23:refs/remotes/origin/w1-23 + fetch = +refs/heads/de-24:refs/remotes/origin/de-24 + fetch = +refs/heads/us-*:refs/remotes/origin/us-* +[branch "w1-23"] + remote = origin + merge = refs/heads/w1-23 +``` +once thats done you need to delete the local reference of the remote branches like this +``` +git branch -d -r origin/us-23 +git branch -d -r origin/us-24 +``` +if you had one of those branches checked out locally (a local copy of the branch) you want to delete those as well +``` +git branch -D us-23 +git branch -D us-24 +``` + +and thats it, now `git fetch` should not pull the branches anymore + +## Partial Clone (Shallow Clone) +To further reduce the size of your local repository, you can also utilize the `--depth` parameter with the `git clone` command. +This creates a shallow clone, fetching only the most recent commits up to the specified depth, thereby ignoring the entire history that you might not need. + +For instance, to clone only the latest commit (depth of 1), you would use the following command: + +``` +git clone -b w1-24 --depth 1 https://github.com/StefanMaron/MSDyn365BC.Code.History +``` + +> [!TIP] +> Using `--depth` implies `--single-branch` unless `--no-single-branch` is given to fetch the histories near the tips of all branches. + +Later, you can deepen your clone by 3 commits (or any other number of commits) with `git fetch --deepen 3` or convert it to a complete clone using `git fetch --unshallow`. ## Disclaimer -All code is owned by Microsoft. You can not do any pull request on this repository. \ No newline at end of file +All code is owned by Microsoft. You can not do any pull request on this repository. diff --git a/base-app.code-workspace b/base-app.code-workspace deleted file mode 100644 index d178f6414e9..00000000000 --- a/base-app.code-workspace +++ /dev/null @@ -1,21 +0,0 @@ -{ - "folders": [ - { - "name": "Base App", - "path": "BaseApp/Source/Base Application" - }, - { - "name": "Base App Tests", - "path": "BaseApp/Test" - } - ], - "settings": { - "allint.enabled": false, - "al.enableCodeActions": false, - "al.enableCodeAnalysis": false, - "al.backgroundCodeAnalysis": false, - "search.exclude": { - "**.xlf": true - } - } -} \ No newline at end of file diff --git a/scripts/Auto_load_versions.ps1 b/scripts/Auto_load_versions.ps1 index 1208ad0644f..e48aaf39b4a 100644 --- a/scripts/Auto_load_versions.ps1 +++ b/scripts/Auto_load_versions.ps1 @@ -1,13 +1,16 @@ -$ErrorActionPreference = "SilentlyContinue" +param ( + [string]$country = 'w1' +) -Set-Alias sz "C:\Program Files\7-Zip\7z.exe" +$ErrorActionPreference = "SilentlyContinue" [System.Collections.ArrayList]$Versions = @() -Get-BCArtifactUrl -select All -Type OnPrem | % { - $Url = $_ - $TempString = $Url.Substring(41) - [version]$Version = $TempString.Substring(0, $TempString.IndexOf('/')) - $country = $TempString.Substring($TempString.IndexOf('/') + 1) +# Get-BCArtifactUrl -select All -Type OnPrem -country $country -after ([DateTime]::Today.AddDays(-1)) | % { +Get-BCArtifactUrl -select All -Type OnPrem -country $country | % { + [System.Uri]$Url = $_ + $TempString = $Url.AbsolutePath + [version]$Version = $TempString.Split('/')[2] + $country = $TempString.Split('/')[3] [hashtable]$objectProperty = @{} $objectProperty.Add('Version', $Version) @@ -22,57 +25,79 @@ Get-BCArtifactUrl -select All -Type OnPrem | % { $Versions | Sort-Object -Property Country, Version | % { [version]$Version = $_.Version - $country = $_.Country + $country = $_.Country.Trim() + Write-Host ($($country)-$($version.ToString())) + + git fetch --all - $CommitDoesNotExist = (git log --all --grep="$($country)-$($version.ToString())") -eq $null + $LastCommit = git log --all --grep="^$($country)-$($version.ToString())$" - if ($CommitDoesNotExist) { + if ($LastCommit.Length -eq 0) { Write-Host "###############################################" Write-Host "Processing $($country) - $($Version.ToString())" Write-Host "###############################################" - - - $LatestCommitIDOfBranchEmpty = git log -n 1 --pretty=format:"%h" "empty" + + $LatestCommitIDOfBranchEmpty = git log -n 1 --pretty=format:"%h" "master" if ($LatestCommitIDOfBranchEmpty -eq $null) { - $LatestCommitIDOfBranchEmpty = git log -n 1 --pretty=format:"%h" "origin/empty" + $LatestCommitIDOfBranchEmpty = git log -n 1 --pretty=format:"%h" "origin/master" } if ($Version.Major -gt 15 -and $Version.Build -gt 5) { - $CommitIDLastCUFromPreviousMajor = git log --all --grep="$($country)-$($version.Major - 1).5" --pretty=format:"%h" + $CommitIDLastCUFromPreviousMajor = git log --all -n 1 --grep="^$($country)-$($version.Major - 1).5" --pretty=format:"%h" } else { $CommitIDLastCUFromPreviousMajor = $null } - $BranchAlreadyExists = ((git branch --list -r "*$($country)-$($Version.Major)*") -ne $null) -or ((git branch --list "*$($country)-$($Version.Major)*") -ne $null) + $BranchAlreadyExists = ((git branch --list -r "origin/$($country)-$($Version.Major)") -ne $null) -or ((git branch --list "$($country)-$($Version.Major)") -ne $null) if ($BranchAlreadyExists) { - git checkout "$($country)-$($Version.Major)" + git switch "$($country)-$($Version.Major)" } else { if ($CommitIDLastCUFromPreviousMajor -ne $null) { - git checkout -b "$($country)-$($Version.Major)" $CommitIDLastCUFromPreviousMajor + git switch -c "$($country)-$($Version.Major)" $CommitIDLastCUFromPreviousMajor } else { - git checkout -b "$($country)-$($Version.Major)" $LatestCommitIDOfBranchEmpty + git switch -c "$($country)-$($Version.Major)" $LatestCommitIDOfBranchEmpty } } - $Paths = Download-Artifacts -artifactUrl $_.URL -includePlatform - $TargetPathOfVersion = $Paths[0] + if ($country -eq 'w1'){ + $Paths = Download-Artifacts -artifactUrl $_.URL -includePlatform + $LocalizationPath = $Paths[0] + $PlatformPath = $Paths[1] + } + else { + $Paths = Download-Artifacts -artifactUrl $_.URL + $LocalizationPath = $Paths + $PlatformPath = '' + } + + #Localization folder + + $TargetPathOfVersion = (Join-Path $LocalizationPath (Get-ChildItem -Path $LocalizationPath -filter "Applications")[0].Name) - if (-not (Test-Path (Join-Path $TargetPathOfVersion 'Applications'))) { - $TargetPathOfVersion = $Paths[1] + if (-not (Test-Path $TargetPathOfVersion)) { + #Platform Folder + $TargetPathOfVersion = (Join-Path $PlatformPath (Get-ChildItem -Path $PlatformPath -filter "Applications")[0].Name) } - & "$PSScriptRoot\UpdateALRepo.ps1" -SourcePath (Join-Path $TargetPathOfVersion Applications) -RepoPath (Split-Path $PSScriptRoot -Parent) - & "$PSScriptRoot\BuildTestsWorkSpace.ps1" + & "scripts/UpdateALRepo.ps1" -SourcePath $TargetPathOfVersion -RepoPath (Split-Path $PSScriptRoot -Parent) -Version $version -Localization $country + & "scripts/BuildTestsWorkSpace.ps1" + + Get-ChildItem -Recurse -Filter "*.xlf" | Remove-Item + + "$($country)-$($version.ToString())" > version.txt + git config user.email "stefanmaron@outlook.de" + git config user.name "Stefan Maron" git add -A | out-null git commit -a -m "$($country)-$($version.ToString())" | out-null git gc | out-null + git push --set-upstream origin "$($country)-$($Version.Major)" - Remove-Item $Paths[0] -Recurse + Flush-ContainerHelperCache -keepDays 0 -ErrorAction SilentlyContinue Write-Host "$($country)-$($version.ToString())" } diff --git a/scripts/GetAllCountries.ps1 b/scripts/GetAllCountries.ps1 new file mode 100644 index 00000000000..7b48bc1bd0b --- /dev/null +++ b/scripts/GetAllCountries.ps1 @@ -0,0 +1,9 @@ +$countries = [System.Collections.ArrayList]::new() +Get-BCArtifactUrl -select All -Type OnPrem | % { + [System.Uri]$Url = $_ + [version]$Version = $Url.AbsolutePath.Split('/')[2] + if ($Version -ge [version]::Parse('15.0.0.0')) { + $Url.AbsolutePath.Split('/')[3] + } +}| Sort-object -unique | % { $countries.Add($_)} +Write-Output "countries={""countries"":$($countries | ConvertTo-Json -Compress)}" >> $Env:GITHUB_OUTPUT \ No newline at end of file diff --git a/scripts/UpdateALRepo.ps1 b/scripts/UpdateALRepo.ps1 index 4b4b39d9ca8..13bb9d17eca 100644 --- a/scripts/UpdateALRepo.ps1 +++ b/scripts/UpdateALRepo.ps1 @@ -3,24 +3,22 @@ param( $Version = '', $BuildFolder = '', $SourcePath, - $RepoPath = '', - $7zipExe = 'C:\Program Files\7-Zip\7z.exe' + $RepoPath = '' ) if (-not $SourcePath) { - $SourcePath = "C:\bcartifacts.cache\onprem\$Version\$Localization\Applications" + $SourcePath = "~/.bcartifacts.cache/sandbox/$Version/$Localization/Applications.DE/" } -Set-Alias sz $7zipExe $zips = Get-ChildItem -Path $SourcePath -Filter *.zip -Recurse Get-ChildItem -Path $RepoPath -Directory -Exclude scripts, .git | Remove-Item -Recurse -Force foreach ($zip in $zips) { - $RelativePath = $zip.FullName -ireplace [regex]::Escape($SourcePath + '\'), '' + $RelativePath = $zip.FullName -ireplace [regex]::Escape($SourcePath + '/'), '' $ZipTargetPath = Join-Path $RepoPath (Split-Path -Path $RelativePath) $ZipNameForTarget = (Split-Path -Path $RelativePath -Leaf).Replace('.zip', '').Replace('..Source', '').Replace('.Source', '') $ZipTargetPath = (Join-Path $ZipTargetPath $ZipNameForTarget) - sz x $zip.FullName -o"$ZipTargetPath" -r -y | out-null + 7z x $zip.FullName -o"$ZipTargetPath" -r -y | out-null } diff --git a/system-app.code-workspace b/system-app.code-workspace deleted file mode 100644 index 0c61423c3b1..00000000000 --- a/system-app.code-workspace +++ /dev/null @@ -1,21 +0,0 @@ -{ - "folders": [ - { - "name": "System App", - "path": "system application/source" - }, - { - "name": "System App Tests", - "path": "system application/test" - } - ], - "settings": { - "allint.enabled": false, - "al.enableCodeActions": false, - "al.enableCodeAnalysis": false, - "al.backgroundCodeAnalysis": false, - "search.exclude": { - "**.xlf": true - } - } -} \ No newline at end of file diff --git a/test-apps.code-workspace b/test-apps.code-workspace deleted file mode 100644 index 66439ebd22e..00000000000 --- a/test-apps.code-workspace +++ /dev/null @@ -1,184 +0,0 @@ -{ - "settings": { - "allint.enabled": false, - "al.enableCodeAnalysis": false, - "al.enableCodeActions": false, - "al.backgroundCodeAnalysis": false, - "search.exclude": { - "**.xlf": true - } - }, - "folders": [ - { - "path": ".\\APIV1\\Test\\_Exclude_APIV1_ Tests" - }, - { - "path": ".\\APIV2\\Test\\_Exclude_APIV2_ Tests" - }, - { - "path": ".\\BaseApp\\Source\\Base Application\\Test Framework" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Bank" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Cash Flow" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Cost Accounting" - }, - { - "path": ".\\BaseApp\\Test\\Tests-CRM integration" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Data Exchange" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Dimension" - }, - { - "path": ".\\BaseApp\\Test\\Tests-ERM" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Fixed Asset" - }, - { - "path": ".\\BaseApp\\Test\\Tests-General Journal" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Graph" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Integration" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Invoicing" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Job" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Local" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Marketing" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Misc" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Monitor Sensitive Fields" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Permissions" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Physical Inventory" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Prepayment" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Rapid Start" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Report" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Resource" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Reverse" - }, - { - "path": ".\\BaseApp\\Test\\Tests-SCM" - }, - { - "path": ".\\BaseApp\\Test\\Tests-SINGLESERVER" - }, - { - "path": ".\\BaseApp\\Test\\Tests-SMB" - }, - { - "path": ".\\BaseApp\\Test\\Tests-SMTP" - }, - { - "path": ".\\BaseApp\\Test\\Tests-TestLibraries" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Upgrade" - }, - { - "path": ".\\BaseApp\\Test\\Tests-User" - }, - { - "path": ".\\BaseApp\\Test\\Tests-VAT" - }, - { - "path": ".\\BaseApp\\Test\\Tests-Workflow" - }, - { - "path": ".\\CompanyHub\\Test\\Company Hub Tests" - }, - { - "path": ".\\DataArchive\\test\\Data Archive Tests" - }, - { - "path": ".\\Email - Current User Connector\\Test\\Email - Current User Connector Tests" - }, - { - "path": ".\\Email - Microsoft 365 Connector\\Test\\Email - Microsoft 365 Connector Tests" - }, - { - "path": ".\\Email - Outlook REST API\\Test" - }, - { - "path": ".\\Email - SMTP Connector\\Test\\Email - SMTP Connector Tests" - }, - { - "path": ".\\EssentialBusinessHeadlines\\Test\\Essential Business Headlines Test" - }, - { - "path": ".\\LatePaymentPredictor\\Test\\Late Payment Prediction Tests" - }, - { - "path": ".\\onprem permissions\\test\\OnPrem Permissions Tests" - }, - { - "path": ".\\paypalpaymentsstandard\\test\\PayPal Payments Standard Tests" - }, - { - "path": ".\\recommendedapps\\test\\Recommended Apps Tests" - }, - { - "path": ".\\salesandinventoryforecast\\test\\Sales and Inventory Forecast Tests" - }, - { - "path": ".\\system application\\source\\System Application\\Email\\src\\Test Email" - }, - { - "path": ".\\system application\\test\\System Application Test" - }, - { - "path": ".\\system application\\test\\System Application Test Library" - }, - { - "path": ".\\system application\\test\\System Application Test\\Extension Management\\testArtifacts" - }, - { - "path": ".\\testframework\\TestLibraries" - }, - { - "path": ".\\testframework\\performancetoolkit\\Performance Toolkit Tests" - }, - { - "path": ".\\testframework\\performancetoolkit\\Performance Toolkit Tests\\src\\Mock Tests" - }, - { - "path": ".\\testframework\\TestRunner\\Test Runner" - }, - { - "path": ".\\vatgroupmanagement\\test\\VAT Group Management Tests" - } - ] -} \ No newline at end of file