create-powerapps-project 1.7.1 → 1.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/plopfile.js CHANGED
@@ -511,7 +511,12 @@ export default async (plop) => {
511
511
  message: 'namespace for form and ribbon scripts:'
512
512
  },
513
513
  packageQuestion,
514
- ...sharedQuestions
514
+ ...sharedQuestions,
515
+ {
516
+ type: 'confirm',
517
+ name: 'deploy',
518
+ message: 'deploy via Azure DevOps Pipelines?'
519
+ }
515
520
  ],
516
521
  actions: (data) => {
517
522
  return [
@@ -529,6 +534,19 @@ export default async (plop) => {
529
534
  destination: process.cwd(),
530
535
  force: true
531
536
  },
537
+ {
538
+ type: 'addMany',
539
+ templateFiles: ['../plop-templates/webresource-deploy/.*'],
540
+ base: '../plop-templates/webresource',
541
+ destination: process.cwd(),
542
+ force: true,
543
+ skip: (answers) => {
544
+ if (!answers.deploy) {
545
+ return 'deployment files not included';
546
+ }
547
+ return;
548
+ }
549
+ },
532
550
  {
533
551
  type: 'addScript',
534
552
  data: {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "create-powerapps-project",
3
3
  "description": "💧 plop generator for Dataverse development",
4
- "version": "1.7.1",
4
+ "version": "1.7.2",
5
5
  "license": "MIT",
6
6
  "exports": "./lib/index.js",
7
7
  "engines": {
@@ -4,54 +4,62 @@ const spawn = require('cross-spawn');
4
4
  const WebpackEventPlugin = require('webpack-event-plugin');
5
5
  const { CleanWebpackPlugin } = require('clean-webpack-plugin');
6
6
 
7
- module.exports = {
8
- entry: config.entries,
7
+ module.exports = (env, argv) => {
8
+ const webpackConfig = {
9
+ entry: config.entries,
9
10
 
10
- output: {
11
- filename: '[name].js',
12
- library: ['{{namespace}}', '[name]'],
13
- path: path.resolve(__dirname, 'lib')
14
- },
15
-
16
- resolve: {
17
- extensions: ['.tsx', '.ts', '.js'],
18
- },
19
-
20
- module: {
21
- rules: [
22
- {
23
- test: /\.ts(x?)$/,
24
- exclude: /node_modules/,
25
- use: ['babel-loader', 'ts-loader']
26
- },
27
- {
28
- test: /\.js$/,
29
- exclude: /node_modules/,
30
- use: ['babel-loader']
31
- },
32
- {
33
- enforce: 'pre',
34
- test: /\.(ts)|(js)$/,
35
- loader: 'source-map-loader'
36
- }
37
- ]
38
- },
11
+ output: {
12
+ filename: '[name].js',
13
+ library: ['{{namespace}}', '[name]'],
14
+ path: path.resolve(__dirname, 'lib')
15
+ },
16
+
17
+ resolve: {
18
+ extensions: ['.tsx', '.ts', '.js'],
19
+ },
20
+
21
+ module: {
22
+ rules: [
23
+ {
24
+ test: /\.ts(x?)$/,
25
+ exclude: /node_modules/,
26
+ use: ['babel-loader', 'ts-loader']
27
+ },
28
+ {
29
+ test: /\.js$/,
30
+ exclude: /node_modules/,
31
+ use: ['babel-loader']
32
+ },
33
+ {
34
+ enforce: 'pre',
35
+ test: /\.(ts)|(js)$/,
36
+ loader: 'source-map-loader'
37
+ }
38
+ ]
39
+ },
39
40
 
40
- plugins: [
41
- new CleanWebpackPlugin(),
42
- new WebpackEventPlugin([
43
- {
44
- hook: 'afterEmit',
45
- callback: compilation => {
46
- if (compilation.errors != null && compilation.errors.length > 0) {
47
- return;
48
- } else {
49
- const assets = Array.from(compilation.emittedAssets || compilation.assets).map(asset => path.basename(asset));
41
+ plugins: [
42
+ new CleanWebpackPlugin(),
43
+ new WebpackEventPlugin([
44
+ {
45
+ hook: 'afterEmit',
46
+ callback: compilation => {
47
+ if (compilation.errors != null && compilation.errors.length > 0) {
48
+ return;
49
+ } else {
50
+ const assets = Array.from(compilation.emittedAssets || compilation.assets).map(asset => path.basename(asset));
50
51
 
51
- spawn('npm', ['run', 'deploy', '-- --files=', assets.join(',')], { cwd: process.cwd(), stdio: 'inherit' });
52
+ spawn('npm', ['run', 'deploy', '-- --files=', assets.join(',')], { cwd: process.cwd(), stdio: 'inherit' });
53
+ }
52
54
  }
53
55
  }
54
- }
55
- ])
56
- ]
57
- }
56
+ ])
57
+ ]
58
+ };
59
+
60
+ if (argv.mode === 'development') {
61
+ config.devtool = 'eval-source-map';
62
+ }
63
+
64
+ return webpackConfig;
65
+ };
@@ -0,0 +1,51 @@
1
+ name: Build and deploy web resources
2
+
3
+ trigger:
4
+ branches:
5
+ include:
6
+ - dev
7
+
8
+ pool:
9
+ vmImage: windows-latest
10
+
11
+ variables:
12
+ serviceConnectionUrl: '{{server}}'
13
+
14
+ steps:
15
+ - task: PowerPlatformToolInstaller@2
16
+ inputs:
17
+ DefaultVersion: true
18
+
19
+ - task: PowerPlatformSetConnectionVariables@2
20
+ displayName: 'set power platform connection variables'
21
+ name: buildConnectionVariables
22
+ inputs:
23
+ authenticationType: 'PowerPlatformSPN'
24
+ PowerPlatformSPN: ''
25
+
26
+ - template: set-spn-token.yml
27
+ parameters:
28
+ serviceConnection: $(serviceConnectionUrl)
29
+ tenantId: $(buildConnectionVariables.BuildTools.TenantId)
30
+ clientId: $(buildConnectionVariables.BuildTools.ApplicationId)
31
+ clientSecret: $(buildConnectionVariables.BuildTools.ClientSecret)
32
+
33
+ - task: NodeTool@0
34
+ inputs:
35
+ versionSpec: "20.x"
36
+ displayName: "install node"
37
+
38
+ - script: |
39
+ {{package}} install
40
+ displayName: {{package}} install
41
+
42
+ - script: |
43
+ {{package}} run build
44
+ displayName: build web resources
45
+
46
+ - script:
47
+ {{package}} run deploy
48
+ displayName: deploy web resources
49
+ env:
50
+ ACCESSTOKEN: $(SpnToken)
51
+
@@ -0,0 +1,34 @@
1
+ function Get-SpnToken {
2
+ param (
3
+ [Parameter(Mandatory)] [String]$tenantId,
4
+ [Parameter(Mandatory)] [String]$clientId,
5
+ [Parameter(Mandatory)] [String]$clientSecret,
6
+ [Parameter(Mandatory)] [String]$dataverseHost
7
+ )
8
+ $body = @{client_id = $clientId; client_secret = $clientSecret; grant_type = "client_credentials"; scope = "https://$dataverseHost/.default"; }
9
+ $OAuthReq = Invoke-RestMethod -Method Post -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" -Body $body
10
+
11
+ return $OAuthReq.access_token
12
+ }
13
+
14
+ function Get-HostFromUrl {
15
+ param (
16
+ [Parameter(Mandatory)] [String]$url
17
+ )
18
+ $options = [System.StringSplitOptions]::RemoveEmptyEntries
19
+ return $url.Split("://", $options)[1].Split("/")[0]
20
+ }
21
+
22
+ function Set-SpnTokenVariableWithinAgent {
23
+ param (
24
+ [Parameter(Mandatory)] [String]$tenantId,
25
+ [Parameter(Mandatory)] [String]$clientId,
26
+ [Parameter(Mandatory)] [String]$clientSecret,
27
+ [Parameter(Mandatory)] [String]$serviceConnection
28
+ )
29
+ $dataverseHost = Get-HostFromUrl $serviceConnection
30
+
31
+ $spnToken = Get-SpnToken $tenantId $clientId $clientSecret $dataverseHost
32
+
33
+ Write-Host "##vso[task.setvariable variable=SpnToken;issecret=true]$spnToken"
34
+ }
@@ -0,0 +1,18 @@
1
+ parameters:
2
+ - name: serviceConnection
3
+ type: string
4
+ - name: tenantId
5
+ type: string
6
+ - name: clientId
7
+ type: string
8
+ - name: clientSecret
9
+ type: string
10
+
11
+ steps:
12
+ - pwsh: |
13
+ $path = "$(Build.SourcesDirectory)"
14
+
15
+ . "$path\entra-authentication.ps1"
16
+ Set-SpnTokenVariableWithinAgent "${{parameters.tenantId}}" "${{parameters.clientId}}" "${{parameters.clientSecret}}" "${{parameters.serviceConnection}}"
17
+
18
+ displayName: "Get access token for use by other tasks"