Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: SkylineCommunications/Low-Code-App-Editor
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 1.0.0.11
Choose a base ref
...
head repository: SkylineCommunications/Low-Code-App-Editor
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
Loading
Showing with 3,505 additions and 1,631 deletions.
  1. +379 −0 .github/workflows/Automation Master SDK Workflow.yml
  2. +14 −21 .github/workflows/dataminer-cicd-automation.yml
  3. +20 −0 .github/workflows/update-catalog-details.yml
  4. +80 −0 .githubtocatalog/auto-generated-catalog.yml
  5. +845 −456 CompanionFiles/Skyline DataMiner/Documents/Low Code App Editor/Install.xml
  6. BIN ...DataMiner/Documents/Low Code App Editor/InstallDependencies/Skyline.DataMiner.CICD.FileSystem.dll
  7. BIN .../Documents/Low Code App Editor/InstallDependencies/Skyline.DataMiner.Core.AppPackageInstaller.dll
  8. BIN ...nts/Low Code App Editor/InstallDependencies/Skyline.DataMiner.Core.DataMinerSystem.Automation.dll
  9. BIN ...cuments/Low Code App Editor/InstallDependencies/Skyline.DataMiner.Core.DataMinerSystem.Common.dll
  10. BIN ...les/Skyline DataMiner/Documents/Low Code App Editor/InstallDependencies/System.IO.Compression.dll
  11. BIN ...e DataMiner/Documents/Low Code App Editor/InstallDependencies/System.Threading.Tasks.Dataflow.dll
  12. BIN Dlls/WebApiLib.dll
  13. +78 −0 Documentation/CATALOG_PRIVATE_MANIFEST.yml
  14. +7 −0 Documentation/CATALOG_PRIVATE_README.md
  15. +1 −0 Documentation/CHANGELOG_1.0.0.1.md
  16. +3 −0 Documentation/CHANGELOG_1.0.0.10.md
  17. +4 −0 Documentation/CHANGELOG_1.0.0.11.md
  18. +9 −0 Documentation/CHANGELOG_1.0.0.12.md
  19. +9 −0 Documentation/CHANGELOG_1.0.0.13.md
  20. +6 −0 Documentation/CHANGELOG_1.0.0.14.md
  21. +6 −0 Documentation/CHANGELOG_1.0.0.15.md
  22. +5 −0 Documentation/CHANGELOG_1.0.0.16.md
  23. +2 −0 Documentation/CHANGELOG_1.0.0.17.md
  24. +1 −0 Documentation/CHANGELOG_1.0.0.2.md
  25. +7 −0 Documentation/CHANGELOG_1.0.0.3.md
  26. +9 −0 Documentation/CHANGELOG_1.0.0.4.md
  27. +3 −0 Documentation/CHANGELOG_1.0.0.5.md
  28. +3 −0 Documentation/CHANGELOG_1.0.0.6.md
  29. +3 −0 Documentation/CHANGELOG_1.0.0.7.md
  30. +8 −0 Documentation/CHANGELOG_1.0.0.8.md
  31. +3 −0 Documentation/CHANGELOG_1.0.0.9.md
  32. BIN Documentation/DeleteDialog.png
  33. BIN Documentation/EditorDialog.png
  34. BIN Documentation/EditorDialog_1_0_0_8.gif
  35. BIN Documentation/ExportDialog.png
  36. BIN Documentation/ImportDialog.png
  37. BIN Documentation/LCAEditor.gif
  38. BIN Documentation/LCAEditor_1_0_0_8.gif
  39. BIN Documentation/OverviewDialog.png
  40. +169 −0 Documentation/README.md
  41. BIN Documentation/SectionsDialog.png
  42. BIN Images/AppPackages_Window.png
  43. BIN Images/DeleteDialog.png
  44. BIN Images/EditorDialog_1_0_0_13.gif
  45. BIN Images/ExportDialog.png
  46. BIN Images/LCAEditor_1_0_0_13.gif
  47. BIN Images/TaskbarUtility_Install.png
  48. +1 −1 Low Code App Editor_1/Controllers/AppEditor/Pages/EditorPagesImportController.cs
  49. +94 −94 Low Code App Editor_1/Controllers/AppEditor/Panels/EditorPanelsImportController.cs
  50. +178 −109 Low Code App Editor_1/Controllers/ExportController.cs
  51. +140 −133 Low Code App Editor_1/Extensions.cs
  52. +95 −94 Low Code App Editor_1/Json/TypeConverter.cs
  53. +18 −12 Low Code App Editor_1/LCA/App.cs
  54. +211 −181 Low Code App Editor_1/LCA/AppVersion.cs
  55. +448 −406 Low Code App Editor_1/Low Code App Editor_1.cs
  56. +27 −0 Low Code App Editor_1/Package/InstallOptions.cs
  57. +2 −2 Low Code App Editor_1/Package/PackageInfo.cs
  58. +7 −1 Low Code App Editor_1/UI/AppListOverview.cs
  59. +67 −30 Low Code App Editor_1/UI/ExportDialog.cs
  60. +142 −0 Low Code App Editor_1Tests/CompanionFiles/Themes.json
  61. +74 −0 Low Code App Editor_1Tests/CompanionFiles/Themes_Extracted.json
  62. +74 −0 Low Code App Editor_1Tests/CompanionFiles/Themes_Merged.json
  63. +92 −0 Low Code App Editor_1Tests/Controllers/ExportControllerTests.cs
  64. +46 −0 Low Code App Editor_1Tests/Low Code App Editor_1Tests.csproj
  65. +12 −0 Low Code App Extensions.sln
  66. +25 −91 README.md
  67. +78 −0 catalog.yml
379 changes: 379 additions & 0 deletions .github/workflows/Automation Master SDK Workflow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,379 @@
name: Automation Master Workflow

# Controls when the workflow will run
on:
# Allows you to run this workflow from another workflow
workflow_call:
outputs:
quality_gate:
description: "Results from Skyline Quality Gate."
value: ${{ jobs.validate_skyline_quality_gate.outputs.quality }}
#artifact-id-release:
artifact-id:
description: "Artifact ID of uploaded Package if successful."
value: ${{ jobs.artifact_creation_registration.outputs.artifact-id }}
# artifact-id-development:
# description: "Artifact ID of dev uploaded Package if successful."
inputs:
referenceName:
required: true
type: string
runNumber:
required: true
type: string
referenceType:
required: true
type: string
repository:
required: true
type: string
owner:
required: true
type: string
sonarCloudProjectName:
required: true
type: string
catalog-identifier:
required: true
type: string
catalog-manifest-path:
required: true
type: string
catalog-readme-path:
required: true
type: string
secrets:
api-key:
required: false
sonarCloudToken:
required: true
azureToken:
required: false

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
validate_skyline_quality_gate:
name: SDK Skyline Quality Gate
runs-on: windows-latest
env:
detected-unit-tests: none
outputs:
quality: ${{ steps.quality-step.outputs.results }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Initialize
run: |
echo "workspace" ${{ github.workspace }}
echo "ref name" ${{ inputs.referenceName }}
echo "run number" ${{ inputs.runNumber }}
echo "ref type" ${{ inputs.referenceType }}
echo "repository" ${{ inputs.repository }}
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'zulu'

- name: Find .sln file
id: findSlnFile
run: |
echo solutionFilePath=$(find . -type f -name '*.sln') >> $GITHUB_OUTPUT
shell: bash
- name: Detect .csproj files
id: detectCsprojFiles
run: |
$csprojFileCount = Get-ChildItem . -Recurse -File -Filter *.csproj | Measure-Object | Select-Object -ExpandProperty Count
$result = "false"
if($csprojFileCount -gt 0){ $result = "true" }
Write-Output "csproj-file-present=$($result)" >> $Env:GITHUB_OUTPUT
shell: pwsh
# TODO: Refactor this in the future to a single stage with a loop that adds all the sources you specify.
- name: Enable Skyline GitHub NuGet Registry
if: inputs.owner == 'SkylineCommunications'
run: |
$SOURCE_NAME="PrivateGitHubNugets"
$SOURCE_URL="https://nuget.pkg.github.com/SkylineCommunications/index.json"
# Check if the source exists. If it does, update it.
if (dotnet nuget list source | Select-String -Pattern $SOURCE_NAME) {
Write-Host "Updating existing source $SOURCE_NAME."
dotnet nuget update source $SOURCE_NAME --source $SOURCE_URL --username USERNAME --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text
} else {
Write-Host "Adding new source $SOURCE_NAME."
dotnet nuget add source $SOURCE_URL --name $SOURCE_NAME --username USERNAME --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text
}
shell: pwsh

- name: Enable Skyline Azure Cloud NuGet Registry
env:
AZURE_TOKEN_EXISTS: ${{ secrets.azureToken }}
if: env.AZURE_TOKEN_EXISTS != null && inputs.owner == 'SkylineCommunications'
run: |
$SOURCE_NAME="CloudNuGets"
$SOURCE_URL="https://pkgs.dev.azure.com/skyline-cloud/Cloud_NuGets/_packaging/CloudNuGet/nuget/v3/index.json"
# Check if the source exists. If it does, update it.
if (dotnet nuget list source | Select-String -Pattern $SOURCE_NAME) {
Write-Host "Updating existing source $SOURCE_NAME."
dotnet nuget update source $SOURCE_NAME --source $SOURCE_URL --username az --password ${{ secrets.azureToken }} --store-password-in-clear-text
} else {
Write-Host "Adding new source $SOURCE_NAME."
dotnet nuget add source $SOURCE_URL --name $SOURCE_NAME --username az --password ${{ secrets.azureToken }} --store-password-in-clear-text
}
- name: Enable Skyline Azure Private NuGet Registry
env:
AZURE_TOKEN_EXISTS: ${{ secrets.azureToken }}
if: env.AZURE_TOKEN_EXISTS != null && inputs.owner == 'SkylineCommunications'
run: |
$SOURCE_NAME="PrivateAzureNuGets"
$SOURCE_URL="https://pkgs.dev.azure.com/skyline-cloud/_packaging/skyline-private-nugets/nuget/v3/index.json"
# Check if the source exists. If it does, update it.
if (dotnet nuget list source | Select-String -Pattern $SOURCE_NAME) {
Write-Host "Updating existing source $SOURCE_NAME."
dotnet nuget update source $SOURCE_NAME --source $SOURCE_URL --username az --password ${{ secrets.azureToken }} --store-password-in-clear-text
} else {
Write-Host "Adding new source $SOURCE_NAME."
dotnet nuget add source $SOURCE_URL --name $SOURCE_NAME --username az --password ${{ secrets.azureToken }} --store-password-in-clear-text
}
- name: Building
if: steps.detectCsprojFiles.outputs.csproj-file-present == 'true'
run: dotnet build "${{ steps.findSlnFile.outputs.solutionFilePath }}" -p:DefineConstants="DCFv1%3BDBInfo%3BALARM_SQUASHING" --configuration Release -nodeReuse:false

- name: Unit Tests
# when not using MSTest you'll need to install coverlet.collector nuget in your test solutions
id: unit-tests
if: steps.detectCsprojFiles.outputs.csproj-file-present == 'true'
run: dotnet test "${{ steps.findSlnFile.outputs.solutionFilePath }}" --filter TestCategory!=IntegrationTest --logger "trx;logfilename=unitTestResults.trx" --collect "XPlat Code Coverage" -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura,opencover
continue-on-error: true

- name: Install SonarCloud scanner
if: steps.detectCsprojFiles.outputs.csproj-file-present == 'true'
run: |
dotnet tool install dotnet-sonarscanner --global
- name: Prepare SonarCloud Variables
id: prepSonarCloudVar
if: steps.detectCsprojFiles.outputs.csproj-file-present == 'true'
run: |
import os
env_file = os.getenv('GITHUB_ENV')
with open(env_file, "a") as myfile:
myfile.write("lowerCaseOwner=" + str.lower("${{ inputs.owner }}"))
shell: python

- name: Get SonarCloud Status
id: get-sonarcloud-status
if: steps.detectCsprojFiles.outputs.csproj-file-present == 'true'
run: |
echo "sonarCloudProjectStatus=$(curl https://${{ secrets.sonarCloudToken }}@sonarcloud.io/api/qualitygates/project_status?projectKey=${{ inputs.sonarCloudProjectName }})" >> $env:GITHUB_OUTPUT
continue-on-error: true

- name: Trigger Initial Analysis
if: steps.detectCsprojFiles.outputs.csproj-file-present == 'true' && fromJson(steps.get-sonarcloud-status.outputs.sonarCloudProjectStatus).projectStatus.status == 'NONE'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
SONAR_TOKEN: ${{ secrets.sonarCloudToken }}
run: |
dotnet sonarscanner begin /k:"${{ inputs.sonarCloudProjectName }}" /o:"${{ env.lowerCaseOwner }}" /d:sonar.token="${{ secrets.sonarCloudToken }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="**/TestResults/**/coverage.opencover.xml" /d:sonar.cs.vstest.reportsPaths="**/TestResults/**.trx"
dotnet build "${{ steps.findSlnFile.outputs.solutionFilePath }}" -p:DefineConstants="DCFv1%3BDBInfo%3BALARM_SQUASHING" --configuration Release -nodeReuse:false
dotnet sonarscanner end /d:sonar.token="${{ secrets.sonarCloudToken }}"
continue-on-error: true

- name: Analyze
if: steps.detectCsprojFiles.outputs.csproj-file-present == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
SONAR_TOKEN: ${{ secrets.sonarCloudToken }}
run: |
dotnet sonarscanner begin /k:"${{ inputs.sonarCloudProjectName }}" /o:"${{ env.lowerCaseOwner }}" /d:sonar.token="${{ secrets.sonarCloudToken }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="**/TestResults/**/coverage.opencover.xml" /d:sonar.cs.vstest.reportsPaths="**/TestResults/**.trx"
dotnet build "${{ steps.findSlnFile.outputs.solutionFilePath }}" -p:DefineConstants="DCFv1%3BDBInfo%3BALARM_SQUASHING" --configuration Release -nodeReuse:false
dotnet sonarscanner end /d:sonar.token="${{ secrets.sonarCloudToken }}"
continue-on-error: true

- name: SonarCloud Quality Gate check
id: sonarcloud-quality-gate-check
if: steps.detectCsprojFiles.outputs.csproj-file-present == 'true'
uses: sonarsource/sonarqube-quality-gate-action@master
with:
scanMetadataReportFile: .sonarqube/out/.sonar/report-task.txt
continue-on-error: true
# Force to fail step after specific time.
timeout-minutes: 5
env:
SONAR_TOKEN: ${{ secrets.sonarCloudToken }}

- name: Quality Gate
id: quality-step
run: |
if "${{ steps.detectCsprojFiles.outputs.csproj-file-present }}" == "false":
print("Quality gate skipped as no .csproj files were detected.")
exit(0)
if "${{ steps.unit-tests.outcome }}" == "failure" or "${{ steps.sonarcloud-quality-gate-check.outcome }}" == "failure" or "${{ steps.sonarcloud-quality-gate-check.outputs.quality-gate-status }}" == "FAILED":
print("Quality gate failed due to:")
if "${{ steps.unit-tests.outcome }}" == "failure":
print("- Test failures")
if "${{ steps.sonarcloud-quality-gate-check.outcome }}" == "failure":
print("- Could not retrieve SonarCloud quality gate status")
if "${{ steps.sonarcloud-quality-gate-check.outputs.quality-gate-status }}" == "FAILED":
print("- Code analysis quality gate failed")
if "${{ steps.unit-tests.outcome }}" == "failure" or "${{ steps.sonarcloud-quality-gate-check.outcome }}" == "failure" or "${{ steps.sonarcloud-quality-gate-check.outputs.quality-gate-status }}" == "FAILED":
exit(1)
shell: python

artifact_creation:
name: Artifact Creation
runs-on: ubuntu-latest
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v4

- name: Find .sln file
id: findSlnFile
run: |
echo solutionFilePath=$(find . -type f -name '*.sln') >> $GITHUB_OUTPUT
shell: bash

# TODO: Refactor this in the future to a single stage with a loop that adds all the sources you specify.
- name: Enable Skyline GitHub NuGet Registry
if: inputs.owner == 'SkylineCommunications'
run: |
$SOURCE_NAME="PrivateGitHubNugets"
$SOURCE_URL="https://nuget.pkg.github.com/SkylineCommunications/index.json"
# Check if the source exists. If it does, update it.
if (dotnet nuget list source | Select-String -Pattern $SOURCE_NAME) {
Write-Host "Updating existing source $SOURCE_NAME."
dotnet nuget update source $SOURCE_NAME --source $SOURCE_URL --username USERNAME --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text
} else {
Write-Host "Adding new source $SOURCE_NAME."
dotnet nuget add source $SOURCE_URL --name $SOURCE_NAME --username USERNAME --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text
}
shell: pwsh

- name: Enable Skyline Azure Cloud NuGet Registry
env:
AZURE_TOKEN_EXISTS: ${{ secrets.azureToken }}
if: env.AZURE_TOKEN_EXISTS != null && inputs.owner == 'SkylineCommunications'
run: |
$SOURCE_NAME="CloudNuGets"
$SOURCE_URL="https://pkgs.dev.azure.com/skyline-cloud/Cloud_NuGets/_packaging/CloudNuGet/nuget/v3/index.json"
# Check if the source exists. If it does, update it.
if (dotnet nuget list source | Select-String -Pattern $SOURCE_NAME) {
Write-Host "Updating existing source $SOURCE_NAME."
dotnet nuget update source $SOURCE_NAME --source $SOURCE_URL --username az --password ${{ secrets.azureToken }} --store-password-in-clear-text
} else {
Write-Host "Adding new source $SOURCE_NAME."
dotnet nuget add source $SOURCE_URL --name $SOURCE_NAME --username az --password ${{ secrets.azureToken }} --store-password-in-clear-text
}
shell: pwsh

- name: Enable Skyline Azure Private NuGet Registry
env:
AZURE_TOKEN_EXISTS: ${{ secrets.azureToken }}
if: env.AZURE_TOKEN_EXISTS != null && inputs.owner == 'SkylineCommunications'
run: |
$SOURCE_NAME="PrivateAzureNuGets"
$SOURCE_URL="https://pkgs.dev.azure.com/skyline-cloud/_packaging/skyline-private-nugets/nuget/v3/index.json"
# Check if the source exists. If it does, update it.
if (dotnet nuget list source | Select-String -Pattern $SOURCE_NAME) {
Write-Host "Updating existing source $SOURCE_NAME."
dotnet nuget update source $SOURCE_NAME --source $SOURCE_URL --username az --password ${{ secrets.azureToken }} --store-password-in-clear-text
} else {
Write-Host "Adding new source $SOURCE_NAME."
dotnet nuget add source $SOURCE_URL --name $SOURCE_NAME --username az --password ${{ secrets.azureToken }} --store-password-in-clear-text
}
shell: pwsh

- name: NuGet restore solution
run: dotnet restore "${{ steps.findSlnFile.outputs.solutionFilePath }}"

- name: Install .NET Tools
run: |
dotnet tool install -g Skyline.DataMiner.CICD.Tools.Packager --version 2.0.*
- name: Create package name
id: packageName
run: |
tempName="${{ inputs.repository }}"
echo name=${tempName//[\"\/\\<>|:*?]/_} >> $GITHUB_OUTPUT
shell: bash

- name: Create dmapp package
if: inputs.referenceType == 'tag'
run: dataminer-package-create dmapp "${{ github.workspace }}" --type automation --version ${{ inputs.referenceName }} --output "${{ github.workspace }}" --name "${{ steps.packageName.outputs.name }}"

- name: Create dmapp package
if: inputs.referenceType != 'tag'
run: dataminer-package-create dmapp "${{ github.workspace }}" --type automation --build-number ${{ inputs.runNumber }} --output "${{ github.workspace }}" --name "${{ steps.packageName.outputs.name }}"

- uses: actions/upload-artifact@v4
with:
name: DataMiner Installation Package
path: "${{ github.workspace }}/${{ steps.packageName.outputs.name }}.dmapp"

artifact_creation_registration:
name: Artifact Registration and Upload
if: inputs.referenceType == 'tag'
runs-on: ubuntu-latest
needs: [validate_skyline_quality_gate,artifact_creation]
env:
result-artifact-id: none
outputs:
artifact-id: ${{ env.result-artifact-id }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Find branch
id: findBranch
run: |
#!/bin/bash
set -e # Exit immediately if a command exits with a non-zero status.
# Capture the branches containing the tag and process them
branches="$(git branch --contains tags/${{ inputs.referenceName }} -r | grep 'origin/' | grep -vE '.*/.*/' | sed 's#origin/##' | paste -sd ",")"
# Append to GitHub Actions output
echo "branch=${branches}" >> $GITHUB_OUTPUT
shell: bash

- name: Target Branch
id: showResult
run: echo "${{ steps.findBranch.outputs.branch }}"

- name: Retrieve Installation Package
id: retrieveInstallationPackage
uses: actions/download-artifact@v4
with:
name: DataMiner Installation Package
path: _DataMinerInstallationPackage

- name: Find Installation package
id: findInstallationPackage
run: |
IFS=$'\n'
echo dmappPackageName=$(find _DataMinerInstallationPackage -type f -name '*.dmapp') >> $GITHUB_OUTPUT
echo $(find _DataMinerInstallationPackage -type f -name '*.dmapp')
unset IFS
shell: bash

- name: Install .NET Tools
run: |
dotnet tool install -g Skyline.DataMiner.CICD.Tools.CatalogUpload --version 2.0.2
- name: Upload to Catalog
id: uploadToCatalog
run: echo "id=$(dataminer-catalog-upload with-registration --path-to-artifact "${{ steps.findInstallationPackage.outputs.dmappPackageName }}" --uri-sourcecode "${{ github.server_url }}/${{ github.repository }}" --artifact-version ${{ inputs.referenceName }} --branch "${{ steps.findBranch.outputs.branch }}" --dm-catalog-token ${{ secrets.api-key }})" --release-notes "${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ inputs.referenceName }}" >> $GITHUB_OUTPUT

- name: (Release) Set artifact Id
run: echo "result-artifact-id=${{ steps.uploadToCatalog.outputs.id }}" >> $GITHUB_ENV
Loading