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

Deployed solution does not contain the Model-driven App #263

Open
meywenz opened this issue Dec 2, 2022 · 3 comments
Open

Deployed solution does not contain the Model-driven App #263

meywenz opened this issue Dec 2, 2022 · 3 comments

Comments

@meywenz
Copy link

meywenz commented Dec 2, 2022

Hi there.

I am using the power-platform actions to deploy solution between environments.

I have noticed that the solution is being deployed successfully, however on the target environment, the Model driven app is not there. There are all the objects that were in the DEV environment but on the TEST or PROD environment the MD app is missing.

Is this some kind of a limitation of these power-platform actions I am not aware of or is it a workflow's fault?

I am including on of the workflows that is responsible of deploying from DEV to TEST environment:

name: Deploy To Test Environment

# Currently triggering this workflow on custom events, using the api https://docs.github.com/en/rest/reference/repos#create-a-repository-dispatch-event
# Can be easily changed to other events https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows
# NOTE: You have to change env variables with appropriate values, if you are modifying it.
on:
 repository_dispatch:
   types: [deploy_to_test]
        
jobs:
  build:

    env:
     solutionName: ${{ github.event.client_payload.solutionname }}
     branchName: ${{ github.event.client_payload.branch }}
     notes: ${{ github.event.client_payload.notes }}
     sourceEnvironmentUserId: ${{ github.event.client_payload.sourceenvironmentuserid }}
     sourceEnvironmentSecretName: ${{ github.event.client_payload.sourceenvironmentsecretname }}
     sourceEnvironmentUrl: ${{ github.event.client_payload.sourceenvironmenturl }}
     targetEnvironmentUserId: ${{ github.event.client_payload.targetenvironmentuserid }}
     targetEnvironmentSecretName: ${{ github.event.client_payload.targetenvironmentsecretname }}
     targetEnvironmentUrl: ${{ github.event.client_payload.targetenvironmenturl }}
     # build variable will go away once we use actions to create the environment
     buildEnvironmentUserId: ${{ github.event.client_payload.buildenvironmentuserid }}
     buildEnvironmentSecretName: ${{ github.event.client_payload.buildenvironmentsecretname }}
     buildEnvironmentUrl: ${{ github.event.client_payload.buildenvironmenturl }}
     requestId: ${{ github.event.client_payload.requestid }}
     projectId: ${{ github.event.client_payload.projectid }}

    runs-on: windows-latest

    steps:
    - name: 'Clone this repo'
      uses: actions/[email protected]

    # Github api create-a-repository-dispatch-event doesn't allow more than 10 properties in the client_payload
    # Hence we are using a request object inside a client_payload to take additional properties.
    # This step can be ignored if using the workflow based on the default events.
    - name: 'Parsing the request from event client_payload'
      id: parse-client-payload-request
      run: |
        $requestPayload = echo "${{ github.event.client_payload.request }}"
        $requestPayloadObj = $requestPayload | ConvertFrom-Json
        $hashProperties = @{}
        foreach ($property in $requestPayloadObj.PSObject.Properties) {
          echo "$($property.Name) :: $($property.value)"
          $hashProperties[$property.Name] = $property.Value
        }

        echo "buildEnvironmentUserId=$($hashProperties.buildenvironmentuserid)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
        echo "buildEnvironmentSecretName=$($hashProperties.buildenvironmentsecretname)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
        echo "buildEnvironmentUrl=$($hashProperties.buildenvironmenturl)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
        echo "requestId=$($hashProperties.requestid)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
        echo "projectId=$($hashProperties.projectId)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
        echo "notes=$($hashProperties.notes)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append


    - name: 'Export the solution from Dev (source) environment'
      id: export-dev
      uses: microsoft/powerplatform-actions/export-solution@latest
   
      with:
        user-name: ${{ env.sourceEnvironmentUserId }}
        password-secret: ${{ secrets[env.sourceEnvironmentSecretName] }}
        solution-name: ${{ env.solutionName }}
        environment-url: ${{ env.sourceEnvironmentUrl }}
        solution-output-file: "${{ env.solutionName }}.zip"
        run-asynchronously: true
        
        

    - name: 'Unpack the exported solution'
      id: unpack-dev
      uses: microsoft/powerplatform-actions/unpack-solution@latest
      with:
        solution-file: "${{ env.solutionName }}.zip"
        solution-folder: "${{ env.solutionName }}"

    - name: 'Commit the unpacked solution to the topic branch'
      id: branch-solution
      uses: microsoft/powerplatform-actions/branch-solution@latest
      with:
       solution-folder: "${{ env.solutionName }}"
       solution-target-folder: "${{ env.solutionName }}"
       repo-token: ${{ secrets.GITHUB_TOKEN }}
       branch-name: ${{ env.branchName }}
       clobber-branch: true
       allow-empty-commit: true

    - name: 'Pack the solution for testing in build environment'
      id: pack-dev
      uses: microsoft/powerplatform-actions/pack-solution@latest
      with:
        solution-folder: ${{env.solutionName}}
        solution-file: "${{env.solutionName}}_Unmanaged.zip"

    - name: 'Import the solution to Build Environment'
      id: import-build
      uses: microsoft/powerplatform-actions/import-solution@latest
      with:
        environment-url: ${{env.buildEnvironmentUrl}}
        user-name: ${{env.buildEnvironmentUserId}}
        password-secret: ${{ secrets[env.buildEnvironmentSecretName] }}
        solution-file: "${{env.solutionName}}_Unmanaged.zip"
        run-asynchronously: true

    - name: 'Export the solution as managed from build environment'
      id: export-build
      uses: microsoft/powerplatform-actions/export-solution@latest
      with:
        user-name: ${{env.buildEnvironmentUserId}}
        password-secret: ${{ secrets[env.buildEnvironmentSecretName] }}
        solution-name: ${{ env.solutionName }}
        environment-url: ${{env.buildEnvironmentUrl}}
        managed: 'true'
        solution-output-file: "${{ env.solutionName }}_managed.zip"
        run-asynchronously: true

    - name: 'Import the managed solution to the Test (target) Environment'
      id: import-test
      uses: microsoft/powerplatform-actions/import-solution@latest
      with:
        environment-url: ${{ env.targetEnvironmentUrl }}
        user-name: ${{ env.targetEnvironmentUserId }}
        password-secret: ${{ secrets[env.targetEnvironmentSecretName] }}
        solution-file: "${{ env.solutionName }}_managed.zip"
        import-as-holding: true
        run-asynchronously: true
        
    - name: 'upgrade-solution'
      uses: microsoft/powerplatform-actions/upgrade-solution@latest
      with:
        environment-url: ${{ env.targetEnvironmentUrl }}
        user-name: ${{ env.targetEnvironmentUserId }}
        password-secret: ${{ secrets[env.targetEnvironmentSecretName] }}
        solution-name: ${{ env.solutionName }}
        async: true

    - name: 'Upload the managed solution to artifact'
      uses: actions/upload-artifact@v3
      with:
        name: ${{env.SolutionName}}
        path: "${{ env.solutionName }}_managed.zip"
     
    # Reading the different power platform action status to upload the status as artifact, to easily communicate it using other jobs.
    - name: Save job status to a file (status.json)
      if: always()
      run: |
        $errors=@{}
        function Process-StepOutputs($stepName, $outCome, $errorMessage) {
          if ($outcome -eq "success" -or $outcome -eq "skipped") {
            return ""
          } else {
            if ($null -ne $errorMessage -and $errorMessage -ne "") {
              $errors["$stepName"] = $errorMessage
            } else {
              $errors["$stepName"] = "Error occured in GitHub action $stepName"
            }
          }
        }

        $outCome = echo "${{ steps.export-dev.outcome }}"
        $errorMsg = echo "${{ steps.export-dev.outputs.errorMessage }}"
        Process-StepOutputs "export-dev" $outCome $errorMsg

        $outCome = echo "${{ steps.unpack-dev.outcome }}"
        $errorMsg = echo "${{ steps.unpack-dev.outputs.errorMessage }}"
        Process-StepOutputs "unpack-dev" $outCome $errorMsg

        $outCome = echo "${{ steps.pack-dev.outcome }}"
        $errorMsg = echo "${{ steps.pack-dev.outputs.errorMessage }}"
        Process-StepOutputs "pack-dev" $outCome $errorMsg

        $outCome = echo "${{ steps.import-build.outcome }}"
        $errorMsg = echo "${{ steps.import-build.outputs.errorMessage }}"
        Process-StepOutputs "import-build" $outCome $errorMsg

        $outCome = echo "${{ steps.export-build.outcome }}"
        $errorMsg = echo "${{ steps.export-build.outputs.errorMessage }}"
        Process-StepOutputs "export-build" $outCome $errorMsg

        $outCome = echo "${{ steps.import-test.outcome }}"
        $errorMsg = echo "${{ steps.import-test.outputs.errorMessage }}"
        Process-StepOutputs "import-test" $outCome $errorMsg

        $jobStatus = echo ${{ job.status }}
        $workflow = echo ${{ github.workflow }}
        $branch = echo ${{ env.branchName }}
        $repo = echo ${{ github.repository }}
        $run = echo ${{ github.run_id }}
        $requestId = echo "${{env.requestId}}"
        $projectid = echo "${{env.projectId}}"
        $errorStr = ConvertTo-Json -InputObject $errors
         $status = @{
          'status' = $jobStatus;
          'workflow' = "$workflow";
          'branch' = $branch;
          'repo' = $repo;
          'run' = $run;
          'requestid' = $requestId;
          'projectid' = "$projectid";
          'errors'= "$errorStr"
        }

        $jsonString = ConvertTo-Json -InputObject $status
        $jsonString > status.json

    - name: Upload job status file as artifact
      if: always()
      uses: actions/upload-artifact@v3
      with:
        name: job_status
        path: status.json

  # This job is to notify the webhook url when the workflow is triggered on the custom event and the payload has the webhook url.
  # Otherwise this job can be ignored.
  notify:
    needs: [build]
    if: always()
    runs-on: windows-latest
    steps:

    - name: Download artifact job_status
      uses: actions/download-artifact@v1
      with:
        name: job_status
      continue-on-error: true

    - name: Reading status & Invoking the webhook
      if: always()
      run: |
        $fileExists = Test-Path job_status/status.json -PathType Leaf
        $uri = echo '${{ github.event.client_payload.webhookurl }}'
        $jsonData = ''
        if ($fileExists) {
          $jsonData = Get-Content job_status/status.json
          echo "Data read from status file :: " $jsonData
        } else {
          $workflow = echo ${{ github.workflow }}
          $branch = echo ${{ github.event.client_payload.branch }}
          $repo = echo ${{ github.repository }}
          $run = echo ${{ github.run_id }}
          $requestId = echo "${{env.requestId}}"
        $projectid = echo "${{env.projectId}}"
          $errors = @{
            "Actions"="Unable to get the status file from the previous job"
          }
          $status = @{
            'status' = "$fileExists";
            'workflow' = "$workflow";
            'branch' = $branch;
            'repo' = $repo;
            'run' = $run;
            'requestid' = $requestId;
            'projectid' = "$projectid";
            'errors' = "$errors"
          }
          $jsonData = ConvertTo-Json -InputObject $status
          echo "Data constructed as status.json file is not present :: " $jsonData
        }
        echo "Invoking the WebHook Url"
        Invoke-RestMethod -Uri $uri -Body $jsonData  -Method POST -ContentType 'application/json'
        echo "Invoked the WebHook Url"

We will be rebuilding our custom ALM App to use Pipelines in the Q2 2023, but for now I'd like to figure out what's the reason that Model-Driven apps are not being deployed.

Thank you.

@paulbreuler
Copy link
Contributor

paulbreuler commented Jan 10, 2023

Sorry for the delay, are you still experiencing this issue? A quick review of your script and I don't see anything major that jumps out.

@meywenz
Copy link
Author

meywenz commented Jan 12, 2023

Hi. I just created a new solution with a MD app and a Canvas app. Only the Canvas app and the Site Map have been deployed

Screenshots:
DEV
TEST

@Southen
Copy link

Southen commented Mar 2, 2023

I ran into what sounds like a related issue recently where the app registration/application user I was using for CI/CD was assigned a D365 security role that was not included in the roles assigned to the modal-driven app. It had enough permissions to successfully export the solution, but silently exported the AppModules tag as an empty element within the customisations.xml without errors or warnings which then resulted in the solution being imported into the target environment successfully, but missing the model app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants