@sap/cds-dk 9.1.3 → 9.2.1

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.
Files changed (78) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/bin/bind.js +2 -0
  3. package/bin/cds.js +2 -0
  4. package/bin/repl.js +4 -2
  5. package/bin/up.js +12 -2
  6. package/bin/util/log.js +8 -1
  7. package/bin/version.js +20 -15
  8. package/lib/bind/shared.js +6 -2
  9. package/lib/build/plugins/helm/files/subcharts/web-application/Chart.yaml +1 -1
  10. package/lib/build/plugins/helm/files/subcharts/web-application/templates/_helpers.tpl +1 -1
  11. package/lib/build/plugins/helm/files/subcharts/web-application/templates/deployment.yaml +8 -0
  12. package/lib/build/plugins/helm/files/subcharts/web-application/templates/virtual-service.yaml +38 -0
  13. package/lib/build/plugins/helm/files/subcharts/web-application/values.schema.json +15 -0
  14. package/lib/build/plugins/helm/files/subcharts/web-application/values.yaml +12 -9
  15. package/lib/build/plugins/helm/index.js +1 -1
  16. package/lib/build/provider/hana/index.js +5 -4
  17. package/lib/build/provider/hana/template/.hdiconfig-all +6 -0
  18. package/lib/compile/to-xsuaa.js +14 -4
  19. package/lib/deploy/to-hana/hana.js +1 -1
  20. package/lib/deploy/to-hana/hdiDeployUtil.js +1 -1
  21. package/lib/init/constants.js +5 -3
  22. package/lib/init/index.js +6 -1
  23. package/lib/init/merge.js +7 -3
  24. package/lib/init/projectReader.js +7 -2
  25. package/lib/init/registries/mta.js +6 -0
  26. package/lib/init/template/ams/files/values.yaml.hbs +5 -0
  27. package/lib/init/template/approuter/files/containerize.yaml.hbs +1 -1
  28. package/lib/init/template/approuter/files/values.yaml.hbs +1 -5
  29. package/lib/init/template/attachments/index.js +1 -1
  30. package/lib/init/template/audit-logging/index.js +1 -1
  31. package/lib/init/template/data/as-json.js +4 -3
  32. package/lib/init/template/data/index.js +1 -0
  33. package/lib/init/template/destination/files/mta.yaml.hbs +1 -20
  34. package/lib/init/template/extension/index.js +1 -1
  35. package/lib/init/template/github-actions/files/cf-github-deploy/action.yaml +48 -0
  36. package/lib/init/template/github-actions/files/cf-setup/action.yaml +53 -0
  37. package/lib/init/template/github-actions/files/kyma-info/action.yaml +37 -0
  38. package/lib/init/template/github-actions/files/kyma-setup/action.yaml +64 -0
  39. package/lib/init/template/github-actions/files/workflows/cf.yaml.hbs +52 -0
  40. package/lib/init/template/github-actions/files/workflows/kyma.yaml.hbs +39 -0
  41. package/lib/init/template/github-actions/files/workflows/test.yaml.hbs +21 -0
  42. package/lib/init/template/github-actions/index.js +69 -0
  43. package/lib/init/template/helm/index.js +5 -1
  44. package/lib/init/template/html5-repo/files/containerize.yaml.hbs +4 -4
  45. package/lib/init/template/html5-repo/files/mta.yaml.hbs +24 -0
  46. package/lib/init/template/html5-repo/files/values.yaml.hbs +2 -1
  47. package/lib/init/template/html5-repo/index.js +9 -3
  48. package/lib/init/template/http/index.js +4 -4
  49. package/lib/init/template/ias/files/package.json.hbs +7 -0
  50. package/lib/init/template/ias/files/values.yaml.hbs +1 -4
  51. package/lib/init/template/ias/index.js +2 -1
  52. package/lib/init/template/kyma/index.js +10 -0
  53. package/lib/init/template/lint/index.js +6 -11
  54. package/lib/init/template/malware-scanner/index.js +1 -1
  55. package/lib/init/template/multitenancy/files/values.yaml.hbs +53 -1
  56. package/lib/init/template/multitenancy/index.js +0 -13
  57. package/lib/init/template/nodejs/files/.vscode/settings.json +2 -2
  58. package/lib/init/template/notifications/index.js +1 -1
  59. package/lib/init/template/pipeline/files/Jenkinsfile +2 -2
  60. package/lib/init/template/pipeline/index.js +1 -1
  61. package/lib/init/template/portal/files/containerize.yaml.hbs +15 -0
  62. package/lib/init/template/portal/files/values.yaml.hbs +1 -1
  63. package/lib/init/template/portal/index.js +9 -1
  64. package/lib/init/template/postgres/index.js +1 -1
  65. package/lib/init/template/sample/index.js +1 -1
  66. package/lib/init/template/test/index.js +1 -1
  67. package/lib/init/template/tiny-sample/index.js +1 -1
  68. package/lib/init/template/typescript/index.js +1 -1
  69. package/lib/init/template/workzone-standard/index.js +13 -4
  70. package/lib/init/template/xsuaa/files/mta.yaml.hbs +8 -0
  71. package/lib/init/template/xsuaa/index.js +11 -0
  72. package/lib/init/template.js +38 -26
  73. package/lib/lint/eslintHelp.json +1 -1
  74. package/lib/util/cf.js +7 -7
  75. package/lib/watch/watched.js +1 -1
  76. package/npm-shrinkwrap.json +24 -24
  77. package/package.json +1 -1
  78. /package/lib/init/template/html5-repo/files/{ui-resources/package.json.hbs → html5-deployer.package.json.hbs} +0 -0
@@ -47,12 +47,14 @@ module.exports = new class ProjectReader {
47
47
  * Returns cds.env using 'production' profile by default as mta deployment is executed with having production profile set.
48
48
  */
49
49
  env4(profile = 'production') {
50
+ const nodeEnv = process.env.NODE_ENV
50
51
  const cdsEnv = process.env.CDS_ENV
51
- process.env.CDS_ENV = profile
52
+ process.env.CDS_ENV = process.env.NODE_ENV = profile
52
53
  try {
53
54
  return cds.env.for('cds')
54
55
  } finally {
55
56
  cdsEnv ? process.env.CDS_ENV = cdsEnv : delete process.env.CDS_ENV
57
+ nodeEnv ? process.env.NODE_ENV = nodeEnv : delete process.env.NODE_ENV
56
58
  }
57
59
  }
58
60
 
@@ -128,7 +130,7 @@ module.exports = new class ProjectReader {
128
130
  const _isJava = () => this.isJava
129
131
  const _extends = () => pkgJson().extends
130
132
  const isApp = name => {
131
- return name !== 'appconfig' && !name.match(/^[._]/) && name !== 'router' && name !== 'portal' && name !== 'workzone'
133
+ return name !== 'appconfig' && !name.match(/^[._]/) && name !== 'router' && name !== 'portal' && name !== 'workzone' && name !== 'html5-deployer'
132
134
  }
133
135
  const reserved = {
134
136
  dependencies: () => pkgJson().dependencies,
@@ -192,10 +194,13 @@ module.exports = new class ProjectReader {
192
194
  hasUI: () => _uiEmbedded() || _uiModule(),
193
195
  isUI5: _ui5,
194
196
  hasUI5: _ui5,
197
+ literal: () => () => text => text,
195
198
  hasMTXRoute: () => _inProd('extensibility') || (_inProd('multitenancy') && !_isJava()),
196
199
  hasMTXRouteJava: () => (_inProd('helm-unified-runtime') || _inProd('helm')) && _isJava() && _inProd('multitenancy'),
200
+ sap: () => cds.cli.options.sap,
197
201
  imageRegistry: () => exists('chart/values.yaml') ? cds.load.yaml(join(cds.root, 'chart/values.yaml')).global?.image?.registry ?? '<your-container-registry-server>' : '<your-container-registry-server>',
198
202
  extendsApp: _extends,
203
+ hasRoles: () => {}, roles: () => {}, // for xs-security generation
199
204
  }
200
205
 
201
206
  // Automatically creates availability checks for `cds add` commands.
@@ -135,6 +135,11 @@ const providedAppApi = {
135
135
  where: { name: 'app-api', 'properties.app-protocol': '${protocol}', 'properties.app-uri': '${default-uri}' }
136
136
  }
137
137
 
138
+ const requiredSrvApi4 = module => ({
139
+ in: [module, 'requires'],
140
+ where: { name: 'srv-api', 'properties.srv-url': '~{srv-api/srv-url}' }
141
+ })
142
+
138
143
  const requiredAppApi4 = module => ({
139
144
  in: [module, 'requires'],
140
145
  where: { name: 'app-api' }
@@ -220,6 +225,7 @@ module.exports = {
220
225
  providedMtxApiSidecar4,
221
226
  requiredMtxApi,
222
227
  requiredMtxSidecarApi4,
228
+ requiredSrvApi4,
223
229
  providedAppApi,
224
230
  requiredAppApi4,
225
231
  requiredJavaApprouterApi4,
@@ -11,3 +11,8 @@ ams-policies-deployer:
11
11
  parameters:
12
12
  credential-type: X509_GENERATED
13
13
  app-identifier: ams-policy-deployer
14
+
15
+ identity:
16
+ parameters:
17
+ authorization:
18
+ enabled: true
@@ -12,4 +12,4 @@ modules:
12
12
  {{/hasHelmUnifiedRuntime}}
13
13
  path: app/router
14
14
  env:
15
- BP_NODE_RUN_SCRIPTS: ""
15
+ BP_NODE_RUN_SCRIPTS: ""
@@ -34,14 +34,10 @@ backendDestinations:
34
34
  service: {{#isJava}}srv{{/isJava}}{{^isJava}}sidecar{{/isJava}}
35
35
  {{/hasMultitenancy}}
36
36
  srv:
37
- expose:
38
- enabled: false
39
37
  networkSecurity:
40
38
  allowNamespaceInternal: true
41
39
  {{#hasMultitenancy}}
42
40
  sidecar:
43
- expose:
44
- enabled: false
45
41
  networkSecurity:
46
42
  allowNamespaceInternal: true
47
- {{/hasMultitenancy}}
43
+ {{/hasMultitenancy}}
@@ -13,7 +13,7 @@ module.exports = class AttachmentsTemplate extends require('../../plugin') {
13
13
  }
14
14
 
15
15
  static hasInProduction(env) {
16
- return !!env.requires?.attachments
16
+ return !!env.requires?.attachments || readProject().dependencies?.['@cap-js/attachments']
17
17
  }
18
18
 
19
19
  async canRun() {
@@ -12,7 +12,7 @@ module.exports = class AuditLoggingTemplate extends require('../../plugin') {
12
12
  }
13
13
 
14
14
  static hasInProduction(env) {
15
- return env.requires?.['audit-log']
15
+ return env.requires?.['audit-log'] || readProject().dependencies?.['@cap-js/audit-logging']
16
16
  }
17
17
 
18
18
  options() {
@@ -228,9 +228,10 @@ function dataForField(element, artifact, csn, record, data, parent, depth, refer
228
228
  return randomIntInRange(range)
229
229
  }
230
230
  case 'cds.hana.REAL':
231
- case 'cds.Decimal': { // Decimal(9,5), Decimal(9), Decimal(precision:5)
231
+ case 'cds.Decimal': { // Decimal(9,5), Decimal(9), Decimal(precision:5), Decimal(2,2)
232
232
  const scale = element.scale ?? (element.precision ? 0 : 2) // scale is 0 if only precision is given
233
- const prec = element.precision ? Math.min(Math.pow(10, element.precision-scale), Number.MAX_SAFE_INTEGER) : 100
233
+ //10^x would allow one digit more than allowed, that's why -1
234
+ const prec = element.precision ? Math.min(Math.pow(10, element.precision - scale) - 1, Number.MAX_SAFE_INTEGER) : 100
234
235
  const range = { from: 0, to: prec }
235
236
  annotatedIntRange(element, range)
236
237
  return +(randomDecimalInRange(range).toFixed(scale))
@@ -550,7 +551,7 @@ function randomDateInRange(dateRange) {
550
551
  function randomDecimalInRange(decimalRange) {
551
552
  const max = decimalRange.to
552
553
  const min = decimalRange.from
553
- const num = min + (randomNumber() % (max - min))
554
+ const num = max === 0 ? 0 : min + (randomNumber() % (max - min))
554
555
  let dec = randomNumber()
555
556
  const divider = Math.pow(10, dec.toString().length)
556
557
  dec = dec / divider
@@ -82,6 +82,7 @@ module.exports = class DataTemplate extends require('../../plugin') {
82
82
 
83
83
  if (contentType === 'csv') {
84
84
  const headerOnly = !cds.cli.options['records'] // compat to old behavior which only creates headers
85
+ if (headerOnly) console.log(`${dim('adding headers only, use --records to create random entries')}`)
85
86
  await asCsv(data, csn, Object.assign({ headerOnly }, dataForParams))
86
87
  }
87
88
 
@@ -22,23 +22,4 @@ resources:
22
22
  type: org.cloudfoundry.managed-service
23
23
  parameters:
24
24
  service: destination
25
- service-plan: lite{{#hasHtml5Repo}}
26
- config:
27
- HTML5Runtime_enabled: true
28
- init_data:
29
- instance:
30
- existing_destinations_policy: update
31
- destinations:
32
- - Name: srv-api
33
- URL: ~{srv-api/srv-url}
34
- Authentication: NoAuthentication
35
- Type: HTTP
36
- ProxyType: Internet
37
- HTML5.ForwardAuthToken: true
38
- HTML5.DynamicDestination: true
39
- - Name: ui5
40
- URL: https://ui5.sap.com
41
- Authentication: NoAuthentication
42
- Type: HTTP
43
- ProxyType: Internet
44
- {{/hasHtml5Repo}}
25
+ service-plan: lite
@@ -8,7 +8,7 @@ const npmPackageRegex = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/
8
8
  module.exports = class ExtensionProjectTemplate extends require('../../plugin') {
9
9
 
10
10
  static help() {
11
- return 'Extension project'
11
+ return 'extension project'
12
12
  }
13
13
 
14
14
  options() {
@@ -0,0 +1,48 @@
1
+ name: GitHub Deployment for Cloud Foundry
2
+ description: "Creates a GitHub deployment for your Cloud Foundry app"
3
+
4
+ inputs:
5
+ app-name:
6
+ description: "Base name of the deployed CAP app"
7
+ required: true
8
+
9
+ runs:
10
+ using: "composite"
11
+ steps:
12
+ - name: Get deployed server URL
13
+ id: get-url
14
+ shell: bash
15
+ run: |
16
+ raw=$(cf app "${{ inputs.app-name }}" | awk '/routes:/ {print $2}')
17
+ raw=$(echo "$raw" | sed -E 's#^https?://##')
18
+ echo "url=https://$raw" >> "$GITHUB_OUTPUT"
19
+
20
+ - name: Create GitHub Deployment
21
+ uses: actions/github-script@v7
22
+ env:
23
+ URL: ${{ steps.get-url.outputs.url }}
24
+ with:
25
+ script: |
26
+ const { owner, repo } = context.repo
27
+ const ref = context.ref
28
+ const url = process.env.URL
29
+
30
+ const deployment = await github.rest.repos.createDeployment({
31
+ owner,
32
+ repo,
33
+ ref,
34
+ required_contexts: [],
35
+ environment: 'Production',
36
+ auto_merge: false,
37
+ description: 'Deployed to Cloud Foundry',
38
+ })
39
+
40
+ await github.rest.repos.createDeploymentStatus({
41
+ owner,
42
+ repo,
43
+ deployment_id: deployment.data.id,
44
+ state: 'success',
45
+ environment_url: url,
46
+ log_url: `https://github.com/${owner}/${repo}/actions/runs/${context.runId}`,
47
+ description: 'CAP app is live',
48
+ })
@@ -0,0 +1,53 @@
1
+ name: Cloud Foundry Setup
2
+ description: "Installs dependencies for Cloud Foundry deployment"
3
+
4
+ inputs:
5
+ cf-version:
6
+ description: "The version of the Cloud Foundry CLI to install"
7
+ required: false
8
+ default: "8.8.3"
9
+ cf-api:
10
+ description: "The Cloud Foundry API endpoint to connect to"
11
+ required: true
12
+ cf-org:
13
+ description: "The Cloud Foundry organization to target"
14
+ required: true
15
+ cf-space:
16
+ description: "The Cloud Foundry space to target"
17
+ required: true
18
+ cf-username:
19
+ description: "The Cloud Foundry username to authenticate with"
20
+ required: true
21
+ cf-password:
22
+ description: "The Cloud Foundry password to authenticate with"
23
+ required: true
24
+
25
+ runs:
26
+ using: composite
27
+ steps:
28
+ - shell: bash
29
+ run: |
30
+ set -e
31
+ echo "Using CF_VERSION=${{ inputs.cf-version }}"
32
+ echo "Using CF_API=${{ inputs.cf-api }}"
33
+ curl -L "https://packages.cloudfoundry.org/stable?release=linux64-binary&version=${{ inputs.cf-version }}&source=github" -o cf-cli.tgz
34
+ mkdir cf-cli && tar -xzf cf-cli.tgz -C cf-cli
35
+ chmod +x cf-cli/cf
36
+ echo "${PWD}/cf-cli" >> $GITHUB_PATH
37
+
38
+ - shell: bash
39
+ run: |
40
+ echo "Installing MBT..."
41
+ npm install -g mbt
42
+
43
+ - shell: bash
44
+ run: |
45
+ echo "Installing CF CLI multiapps plugin..."
46
+ cf install-plugin multiapps -f
47
+
48
+ - shell: bash
49
+ run: |
50
+ echo "Authenticating to Cloud Foundry..."
51
+ cf api "${{ inputs.cf-api }}"
52
+ cf auth "${{ inputs.cf-username }}" "${{ inputs.cf-password }}"
53
+ cf target -o "${{ inputs.cf-org }}" -s "${{ inputs.cf-space }}"
@@ -0,0 +1,37 @@
1
+ name: Kyma Info
2
+
3
+ description: "Prints post-deployment information for Kyma applications"
4
+
5
+ inputs:
6
+ app:
7
+ description: App Name
8
+ required: true
9
+
10
+ runs:
11
+ using: "composite"
12
+ steps:
13
+ - name: Get Events
14
+ shell: bash
15
+ run: kubectl get events --sort-by='.lastTimestamp' | tail -n 10
16
+ - name: Get Pods
17
+ shell: bash
18
+ run: kubectl get pods
19
+ - name: Get Secrets
20
+ shell: bash
21
+ run: kubectl get secrets
22
+ - name: Get Service Instances
23
+ shell: bash
24
+ run: kubectl get serviceinstances
25
+ - name: Get Service Bindings
26
+ shell: bash
27
+ run: kubectl get servicebindings
28
+ - shell: bash
29
+ run: |
30
+ echo "::group::Kyma Logs for ${{ inputs.app }}-srv"
31
+ kubectl get pods --no-headers | awk '{print $1}' | grep "${{ inputs.app }}.*-srv" | xargs -r -I % kubectl logs % --since=10m
32
+ echo "::endgroup::"
33
+ - shell: bash
34
+ run: |
35
+ echo "::group::Kyma Logs for ${{ inputs.app }}-approuter"
36
+ kubectl get pods --no-headers | awk '{print $1}' | grep "${{ inputs.app }}.*-approuter" | xargs -r -I % kubectl logs % --since=10m
37
+ echo "::endgroup::"
@@ -0,0 +1,64 @@
1
+ name: Kyma Setup
2
+
3
+ description: "Installs dependencies for Kyma deployment"
4
+
5
+ inputs:
6
+ registry:
7
+ description: Image Registry
8
+ required: true
9
+ user:
10
+ description: Registry User
11
+ required: true
12
+ password:
13
+ description: Registry Password
14
+ required: true
15
+ kube-config:
16
+ description: Base64-encoded Kubernetes Config
17
+ required: true
18
+
19
+ runs:
20
+ using: "composite"
21
+ steps:
22
+ - run: apt-get update -y
23
+ shell: bash
24
+ - run: apt-get install software-properties-common -y
25
+ shell: bash
26
+ - run: apt-get install curl ca-certificates -y
27
+ shell: bash
28
+ - run: apt install sudo
29
+ shell: bash
30
+ - run: curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
31
+ shell: bash
32
+ - run: echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
33
+ shell: bash
34
+ - run: apt-get update -y
35
+ shell: bash
36
+ - run: apt-get install make -y
37
+ shell: bash
38
+ - run: apt-get install maven -y
39
+ shell: bash
40
+ - run: apt-get install docker.io -y
41
+ shell: bash
42
+ - run: (curl -sSL "https://github.com/buildpacks/pack/releases/download/v0.31.0/pack-v0.31.0-linux.tgz" | sudo tar -C /usr/local/bin/ --no-same-owner -xzv pack)
43
+ shell: bash
44
+ - run: apt-get install kubectl -y
45
+ shell: bash
46
+ - run: curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
47
+ shell: bash
48
+ - run: sudo apt-get install apt-transport-https --yes
49
+ shell: bash
50
+ - run: echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
51
+ shell: bash
52
+ - run: sudo apt-get update
53
+ shell: bash
54
+ - run: sudo apt-get install helm
55
+ shell: bash
56
+ - run: npm install -g ctz
57
+ shell: bash
58
+ - shell: bash
59
+ run: |
60
+ mkdir ${HOME}/kyma-binaries
61
+ export PATH=${HOME}/kyma-binaries/:$PATH
62
+ echo "${{ inputs.password }}" | docker login "${{ inputs.registry }}" -u "${{ inputs.user }}" --password-stdin
63
+ mkdir ${HOME}/.kube
64
+ echo "${{ inputs.kube-config }}" | base64 --decode > ${HOME}/.kube/config
@@ -0,0 +1,52 @@
1
+ name: Cloud Foundry
2
+
3
+ on:
4
+ workflow_call:
5
+ workflow_dispatch:
6
+ merge_group:
7
+ push:
8
+ branches:
9
+ - main
10
+
11
+ concurrency:
12
+ group: {{#literal}}cf-${{ github.workflow }}-${{ github.head_ref || github.run_id }}{{/literal}}
13
+ cancel-in-progress: true
14
+
15
+ env:
16
+ APP_NAME: {{ appName }}
17
+ jobs:
18
+ deploy:
19
+ runs-on: {{#sap}}[self-hosted, solinas]{{/sap}}{{^sap}}ubuntu-latest{{/sap}}
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ - uses: actions/setup-node@v4
23
+ with:
24
+ node-version: 22
25
+ - uses: ./.github/actions/cf-setup # cap-js/cf-setup@v1
26
+ with:
27
+ cf-api: {{#literal}}${{ vars.CF_API }}{{/literal}}
28
+ cf-org: {{#literal}}${{ vars.CF_ORG }}{{/literal}}
29
+ cf-space: {{#literal}}${{ vars.CF_SPACE }}{{/literal}}
30
+ cf-username: {{#literal}}${{ vars.CF_USERNAME }}{{/literal}}
31
+ cf-password: {{#literal}}${{ secrets.CF_PASSWORD }}{{/literal}}
32
+ - run: npm install
33
+ - run: npx cds up
34
+
35
+ - uses: ./.github/actions/cf-github-deploy
36
+ with:
37
+ app-name: {{#literal}}${{ env.APP_NAME }}{{/literal}}
38
+
39
+ {{#hasApprouter}}
40
+ - run: cf logs "${{ env.APP_NAME }}" --recent
41
+ if: always()
42
+ {{/hasApprouter}}
43
+ - run: cf logs "${{ env.APP_NAME }}-srv" --recent
44
+ if: always()
45
+ {{^hasMultitenancy}}
46
+ - run: cf logs "${{ env.APP_NAME }}-db-deployer" --recent
47
+ if: always()
48
+ {{/hasMultitenancy}}
49
+ {{#hasMultitenancy}}
50
+ - run: cf logs "${{ env.APP_NAME }}-mtx" --recent
51
+ if: always()
52
+ {{/hasMultitenancy}}
@@ -0,0 +1,39 @@
1
+ name: Kyma
2
+
3
+ on:
4
+ workflow_call:
5
+ workflow_dispatch:
6
+ merge_group:
7
+ push:
8
+ branches:
9
+ - main
10
+
11
+ concurrency:
12
+ group: {{#literal}}deploy-${{ github.workflow }}-${{ github.head_ref || github.run_id }}{{/literal}}
13
+ cancel-in-progress: true
14
+
15
+ env:
16
+ APP_NAME: {{ appName }}
17
+ jobs:
18
+ deploy:
19
+ runs-on: [self-hosted, {{#sap}}solinas{{/sap}}{{^sap}}ubuntu-latest{{/sap}}]
20
+ container:
21
+ image: public.int.repositories.cloud.sap/ubuntu:24.04
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+ - uses: actions/setup-node@v4
25
+ with:
26
+ node-version: 22
27
+ - uses: ./.github/actions/kyma-setup
28
+ with:
29
+ registry: {{#literal}}${{ vars.DOCKER_REGISTRY }}{{/literal}}
30
+ user: {{#literal}}${{ vars.DOCKER_USERNAME }}{{/literal}}
31
+ password: {{#literal}}${{ secrets.DOCKER_PASSWORD }}{{/literal}}
32
+ kube-config: {{#literal}}${{ secrets.KUBE_CONFIG }}{{/literal}}
33
+ - run: npm clean-install
34
+ - run: npx cds up --to k8s
35
+
36
+ - uses: ./.github/actions/kyma-info
37
+ if: always()
38
+ with:
39
+ app: {{#literal}}${{ env.APP_NAME }}{{/literal}}
@@ -0,0 +1,21 @@
1
+ name: Tests
2
+
3
+ on:
4
+ workflow_call:
5
+ workflow_dispatch:
6
+ pull_request:
7
+ merge_group:
8
+ push:
9
+ branches:
10
+ - main
11
+
12
+ jobs:
13
+ tests:
14
+ runs-on: [self-hosted, {{#sap}}solinas{{/sap}}{{^sap}}ubuntu-latest{{/sap}}]
15
+ steps:
16
+ - uses: actions/setup-node@v4
17
+ with:
18
+ node-version: 22
19
+ - uses: actions/checkout@v4
20
+ - run: npm install
21
+ - run: npm test
@@ -0,0 +1,69 @@
1
+ const path = require('node:path')
2
+ const { readProject } = require('../../projectReader')
3
+ const { renderAndCopy } = require('../../template')
4
+ const cds = require('../../../cds')
5
+ const { exists, copy } = cds.utils
6
+
7
+ module.exports = class GitHubActionTemplate extends require('../../plugin') {
8
+
9
+ static hasInProduction() {
10
+ return exists('.github/workflows/test.yaml')
11
+ }
12
+
13
+ options() {
14
+ return {
15
+ 'sap': {
16
+ type: 'boolean'
17
+ }
18
+ }
19
+ }
20
+
21
+ static help() {
22
+ return 'CI/CD pipeline via GitHub Actions'
23
+ }
24
+
25
+ async run() {
26
+ const out = '.github/workflows/test.yaml'
27
+ if (!exists(out) || cds.cli.options.force) {
28
+ await renderAndCopy(path.join(__dirname, 'files/workflows/test.yaml.hbs'), out, { sap: cds.cli.options.sap })
29
+ } else {
30
+ console.log('> skipping ' + out)
31
+ }
32
+ }
33
+
34
+ async combine() {
35
+ const project = readProject()
36
+ const { hasMta, hasHelm } = project, { force } = cds.cli.options
37
+ project.literal = () => text => text
38
+ project.sap = cds.cli.options.sap
39
+ if (hasMta) {
40
+ const cf = '.github/workflows/cf.yaml'
41
+ if (!exists(cf) || force) {
42
+ await renderAndCopy(path.join(__dirname, 'files/workflows/cf.yaml.hbs'), cf, project)
43
+ }
44
+ const cfSetup = '.github/actions/cf-setup'
45
+ if (!exists(cfSetup) || force) {
46
+ await copy(path.join(__dirname, 'files/cf-setup'), cfSetup)
47
+ }
48
+ const cfGithub = '.github/actions/cf-github-deploy'
49
+ if (!exists(cfGithub) || force) {
50
+ await copy(path.join(__dirname, 'files/cf-github-deploy'), cfGithub)
51
+ }
52
+ }
53
+ if (hasHelm) {
54
+ const kyma = '.github/workflows/kyma.yaml'
55
+ if (!exists(kyma) || force) {
56
+ await renderAndCopy(path.join(__dirname, 'files/workflows/kyma.yaml.hbs'), kyma, project)
57
+ }
58
+ const kymaSetup = '.github/actions/kyma-setup'
59
+ if (!exists(kymaSetup) || force) {
60
+ await copy(path.join(__dirname, 'files/kyma-setup'), kymaSetup)
61
+ }
62
+
63
+ const kymaInfo = '.github/actions/kyma-info'
64
+ if (!exists(kymaInfo) || force) {
65
+ await copy(path.join(__dirname, 'files/kyma-info'), kymaInfo)
66
+ }
67
+ }
68
+ }
69
+ }
@@ -101,7 +101,11 @@ module.exports = class HelmTemplate extends require('../../plugin') {
101
101
  }
102
102
  if (hasMultitenancy) {
103
103
  await this._mergeDependency('web-application', 'sidecar')
104
- await this._mergeDependency('service-instance', 'saas-registry')
104
+ if (hasXsuaa) {
105
+ await this._mergeDependency('service-instance', 'saas-registry')
106
+ } else {
107
+ await this._mergeDependency('service-instance', 'subscription-manager')
108
+ }
105
109
  }
106
110
  if (hasDestination) {
107
111
  await this._mergeDependency('service-instance', 'destination')
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  before-all:
3
3
  {{#hasUI5}}
4
- - mkdir -p ui-resources/resources
4
+ - mkdir -p app/html5-deployer/resources
5
5
  {{#apps}}
6
6
  - npm i --prefix app/{{app}}
7
7
  - npm run build --prefix app/{{app}}
8
8
  # zip filename should match the archiveName specified in ui5-deploy.yaml
9
- - cp -f app/{{app}}/dist/{{app}}.zip ui-resources/resources/{{app}}.zip
9
+ - cp -f app/{{app}}/dist/{{app}}.zip app/html5-deployer/resources/{{app}}.zip
10
10
  {{/apps}}
11
11
  {{/hasUI5}}
12
12
  modules:
@@ -20,6 +20,6 @@ modules:
20
20
  type: nodejs
21
21
  builder: builder-jammy-base
22
22
  {{/hasHelmUnifiedRuntime}}
23
- path: ui-resources
23
+ path: app/html5-deployer
24
24
  env:
25
- BP_NODE_RUN_SCRIPTS: ""
25
+ BP_NODE_RUN_SCRIPTS: ""
@@ -25,9 +25,14 @@ modules:
25
25
  type: com.sap.application.content
26
26
  path: {{#isNodejs}}gen{{/isNodejs}}{{#isJava}}.{{/isJava}}
27
27
  requires:
28
+ - name: {{appName}}-auth
29
+ - name: srv-api
28
30
  - name: {{appName}}-html5-repo-host
29
31
  parameters:
30
32
  content-target: true
33
+ config:
34
+ HTML5Runtime_enabled: true{{#hasIas}}
35
+ IASDependencyName: {{appName}}-api{{/hasIas}}
31
36
  build-parameters:
32
37
  build-result: {{#isNodejs}}{{& appPath }}{{/isNodejs}}{{#isJava}}resources{{/isJava}}
33
38
  requires:
@@ -37,6 +42,25 @@ modules:
37
42
  - {{app}}.zip
38
43
  target-path: {{#isNodejs}}{{& appPath }}{{/isNodejs}}{{#isJava}}resources{{/isJava}}
39
44
  {{/apps}}
45
+ parameters:
46
+ config:
47
+ HTML5Runtime_enabled: true
48
+ init_data:
49
+ instance:
50
+ existing_destinations_policy: update
51
+ destinations:
52
+ - Name: srv-api
53
+ URL: ~{srv-api/srv-url}
54
+ Authentication: NoAuthentication
55
+ Type: HTTP
56
+ ProxyType: Internet
57
+ HTML5.ForwardAuthToken: true
58
+ HTML5.DynamicDestination: true
59
+ - Name: ui5
60
+ URL: https://ui5.sap.com
61
+ Authentication: NoAuthentication
62
+ Type: HTTP
63
+ ProxyType: Internet
40
64
 
41
65
  {{#apps}}
42
66
  - name: {{strippedAppName}}{{strippedApp}}
@@ -16,10 +16,11 @@ html5-apps-deployer:
16
16
  serviceInstanceName: xsuaa
17
17
  {{/hasXsuaa}}
18
18
  {{#hasIas}}
19
- ias:
19
+ identity:
20
20
  serviceInstanceName: identity
21
21
  parameters:
22
22
  credential-type: X509_GENERATED
23
+ app-identifier: html5-deployer
23
24
  {{/hasIas}}
24
25
  destination:
25
26
  serviceInstanceName: destination