@devopsplaybook.io/common-utils 1.0.0-beta.5.18ca754

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 (51) hide show
  1. package/.github/workflows/main-build.yml +17 -0
  2. package/.github/workflows/npm-upgrade.yml +16 -0
  3. package/.github/workflows/pr-check.yml +26 -0
  4. package/.github/workflows/reusable-merge-build.yml +141 -0
  5. package/.github/workflows/reusable-npm-merge.yml +135 -0
  6. package/.github/workflows/reusable-npm-pr.yml +153 -0
  7. package/.github/workflows/reusable-npm-upgrade.yml +92 -0
  8. package/.github/workflows/reusable-pr-verify.yml +135 -0
  9. package/AGENTS.md +84 -0
  10. package/README.md +413 -0
  11. package/dist/index.d.ts +8 -0
  12. package/dist/index.js +24 -0
  13. package/dist/src/ConfigBase.d.ts +104 -0
  14. package/dist/src/ConfigBase.js +201 -0
  15. package/dist/src/DbUtils.d.ts +50 -0
  16. package/dist/src/DbUtils.js +117 -0
  17. package/dist/src/DbUtilsNoTelemetry.d.ts +27 -0
  18. package/dist/src/DbUtilsNoTelemetry.js +89 -0
  19. package/dist/src/OTelContext.d.ts +35 -0
  20. package/dist/src/OTelContext.js +42 -0
  21. package/dist/src/PostgresDbUtils.d.ts +52 -0
  22. package/dist/src/PostgresDbUtils.js +217 -0
  23. package/dist/src/SqlDbUtils.d.ts +40 -0
  24. package/dist/src/SqlDbUtils.js +156 -0
  25. package/dist/src/SystemCommand.d.ts +9 -0
  26. package/dist/src/SystemCommand.js +56 -0
  27. package/dist/src/Timeout.d.ts +6 -0
  28. package/dist/src/Timeout.js +15 -0
  29. package/eslint.config.mjs +10 -0
  30. package/index.ts +8 -0
  31. package/jest.config.js +13 -0
  32. package/package.json +50 -0
  33. package/prettierrc.json +5 -0
  34. package/src/ConfigBase.spec.ts +108 -0
  35. package/src/ConfigBase.ts +213 -0
  36. package/src/DbUtils.spec.ts +23 -0
  37. package/src/DbUtils.ts +118 -0
  38. package/src/DbUtilsNoTelemetry.spec.ts +174 -0
  39. package/src/DbUtilsNoTelemetry.ts +121 -0
  40. package/src/OTelContext.spec.ts +58 -0
  41. package/src/OTelContext.ts +65 -0
  42. package/src/PostgresDbUtils.spec.ts +155 -0
  43. package/src/PostgresDbUtils.ts +233 -0
  44. package/src/SqlDbUtils.spec.ts +111 -0
  45. package/src/SqlDbUtils.ts +153 -0
  46. package/src/SystemCommand.spec.ts +18 -0
  47. package/src/SystemCommand.ts +23 -0
  48. package/src/Timeout.spec.ts +18 -0
  49. package/src/Timeout.ts +12 -0
  50. package/tsconfig.json +14 -0
  51. package/tsconfig.spec.json +7 -0
@@ -0,0 +1,17 @@
1
+ name: Main Build
2
+
3
+ on:
4
+ push:
5
+ branches: ["main"]
6
+
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ npm-merge:
11
+ uses: devopsplaybook-io/common-utils/.github/workflows/reusable-npm-merge.yml@main
12
+ with:
13
+ npm_package_name: "@devopsplaybook.io/common-utils"
14
+ secrets:
15
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
16
+ QUALITY_DASHBOARD_URL: ${{ secrets.QUALITY_DASHBOARD_URL }}
17
+ QUALITY_DASHBOARD_TOKEN: ${{ secrets.QUALITY_DASHBOARD_TOKEN }}
@@ -0,0 +1,16 @@
1
+ name: NPM Upgrade
2
+
3
+ on:
4
+ schedule:
5
+ - cron: "0 6 * * 1"
6
+
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ npm-upgrade:
11
+ uses: devopsplaybook-io/common-utils/.github/workflows/reusable-npm-upgrade.yml@main
12
+ permissions:
13
+ contents: write
14
+ pull-requests: write
15
+ with:
16
+ npm_services: "[]"
@@ -0,0 +1,26 @@
1
+ name: PR Check
2
+
3
+ on:
4
+ pull_request:
5
+ branches: ["main"]
6
+
7
+ workflow_dispatch:
8
+
9
+ concurrency:
10
+ group: pr-${{ github.event.pull_request.number || github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ permissions:
14
+ contents: read
15
+ pull-requests: write
16
+ issues: write
17
+
18
+ jobs:
19
+ npm-pr:
20
+ uses: devopsplaybook-io/common-utils/.github/workflows/reusable-npm-pr.yml@main
21
+ with:
22
+ npm_package_name: "@devopsplaybook.io/common-utils"
23
+ secrets:
24
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
25
+ QUALITY_DASHBOARD_URL: ${{ secrets.QUALITY_DASHBOARD_URL }}
26
+ QUALITY_DASHBOARD_TOKEN: ${{ secrets.QUALITY_DASHBOARD_TOKEN }}
@@ -0,0 +1,141 @@
1
+ name: "Reusable: Merge Build"
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ docker_platforms:
7
+ description: "Docker platforms to build for"
8
+ required: false
9
+ type: string
10
+ default: "linux/arm64/v8,linux/amd64"
11
+ node_app_directories:
12
+ description: "JSON array of Node.js app directories to build, lint, and test"
13
+ required: false
14
+ type: string
15
+ default: ""
16
+ node_version:
17
+ description: "Node.js version to use"
18
+ required: false
19
+ type: string
20
+ default: "22"
21
+ secrets:
22
+ DOCKER_HUB_USERNAME:
23
+ required: true
24
+ DOCKER_HUB_ACCESS_TOKEN:
25
+ required: true
26
+ QUALITY_DASHBOARD_TOKEN:
27
+ required: false
28
+ QUALITY_DASHBOARD_URL:
29
+ required: false
30
+
31
+ jobs:
32
+ node-build:
33
+ if: inputs.node_app_directories != ''
34
+ strategy:
35
+ matrix:
36
+ app: ${{ fromJSON(inputs.node_app_directories) }}
37
+ runs-on: ubuntu-latest
38
+ defaults:
39
+ run:
40
+ working-directory: ${{ matrix.app }}
41
+ steps:
42
+ - uses: actions/checkout@v6
43
+
44
+ - name: Setup Node.js
45
+ uses: actions/setup-node@v4
46
+ with:
47
+ node-version: ${{ inputs.node_version }}
48
+ cache: "npm"
49
+ cache-dependency-path: ${{ matrix.app }}/package-lock.json
50
+
51
+ - name: Install dependencies
52
+ run: npm ci
53
+
54
+ - name: Build
55
+ run: npm run build
56
+
57
+ - name: Lint
58
+ run: npm run lint
59
+
60
+ - name: Test
61
+ run: npm run test
62
+
63
+ - name: Zip coverage and upload to Quality Dashboard
64
+ if: always()
65
+ env:
66
+ QUALITY_DASHBOARD_URL: ${{ secrets.QUALITY_DASHBOARD_URL }}
67
+ QUALITY_DASHBOARD_TOKEN: ${{ secrets.QUALITY_DASHBOARD_TOKEN }}
68
+ run: |
69
+ APP_NAME="${{ matrix.app }}"
70
+ PACKAGE_NAME=$(node -p "require('./package.json').name")
71
+ REPORT_KEY="$(echo "$APP_NAME" | sed 's/[^a-zA-Z0-9._:\-\/]/_/g')_coverage"
72
+
73
+ if [ -d coverage ]; then
74
+ if [ -z "$QUALITY_DASHBOARD_URL" ] || [ -z "$QUALITY_DASHBOARD_TOKEN" ]; then
75
+ echo "Quality Dashboard URL or token not set, skipping upload"
76
+ exit 0
77
+ fi
78
+ # Zip coverage contents at root level so the jest processor
79
+ # finds coverage-final.json / clover.xml directly
80
+ (cd coverage && zip -r "${{ runner.temp }}/coverage.zip" .)
81
+
82
+ META=$(jq -n \
83
+ --arg key "$REPORT_KEY" \
84
+ --arg pkg "$PACKAGE_NAME" \
85
+ '{
86
+ key: $key,
87
+ displayName: "Coverage: \($pkg)",
88
+ processor: "jest"
89
+ }')
90
+
91
+ echo "Uploading coverage: $REPORT_KEY"
92
+ HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
93
+ -X POST "$QUALITY_DASHBOARD_URL/api/reports/" \
94
+ -H "x-upload-token: $QUALITY_DASHBOARD_TOKEN" \
95
+ -F "meta=$META" \
96
+ -F "file=@${{ runner.temp }}/coverage.zip" \
97
+ --max-time 30)
98
+
99
+ if [ "$HTTP_CODE" = "201" ]; then
100
+ echo "\u2713 Coverage uploaded ($HTTP_CODE)"
101
+ else
102
+ echo "\u26a0 Upload returned HTTP $HTTP_CODE"
103
+ fi
104
+ else
105
+ echo "No coverage/ directory found, skipping upload"
106
+ fi
107
+
108
+ docker-build:
109
+ runs-on: ubuntu-latest
110
+ steps:
111
+ - uses: actions/checkout@v6
112
+
113
+ - name: Set up QEMU
114
+ uses: docker/setup-qemu-action@v4
115
+
116
+ - name: Set up Docker Buildx
117
+ uses: docker/setup-buildx-action@v4
118
+
119
+ - name: Login to Docker Hub
120
+ uses: docker/login-action@v4
121
+ with:
122
+ username: ${{ secrets.DOCKER_HUB_USERNAME }}
123
+ password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
124
+
125
+ - name: Build and Push Docker Image
126
+ run: |
127
+ set -e
128
+ SERVICE_NAME=$(cat package.json | jq -r '.name')
129
+ SERVICE_VERSION=$(cat package.json | jq -r '.version')
130
+ SERVICE_VERSION_MAJOR=$(echo "${SERVICE_VERSION}" | cut -f1 -d".")
131
+ SERVICE_VERSION_MINOR=$(echo "${SERVICE_VERSION}" | cut -f1-2 -d".")
132
+ echo "Building ${SERVICE_NAME}:${SERVICE_VERSION}"
133
+ docker buildx build \
134
+ --platform ${{ inputs.docker_platforms }} \
135
+ --push \
136
+ -f Dockerfile \
137
+ -t ${{ secrets.DOCKER_HUB_USERNAME }}/${SERVICE_NAME}:latest \
138
+ -t ${{ secrets.DOCKER_HUB_USERNAME }}/${SERVICE_NAME}:${SERVICE_VERSION} \
139
+ -t ${{ secrets.DOCKER_HUB_USERNAME }}/${SERVICE_NAME}:${SERVICE_VERSION_MAJOR} \
140
+ -t ${{ secrets.DOCKER_HUB_USERNAME }}/${SERVICE_NAME}:${SERVICE_VERSION_MINOR} \
141
+ .
@@ -0,0 +1,135 @@
1
+ name: "Reusable: NPM Merge"
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ node_version:
7
+ description: "Node.js version to use"
8
+ required: false
9
+ type: string
10
+ default: "18"
11
+ npm_package_name:
12
+ description: "NPM package name (e.g. @devopsplaybook.io/otel-utils)"
13
+ required: true
14
+ type: string
15
+ secrets:
16
+ NPM_TOKEN:
17
+ required: true
18
+ QUALITY_DASHBOARD_TOKEN:
19
+ required: false
20
+ QUALITY_DASHBOARD_URL:
21
+ required: false
22
+
23
+ jobs:
24
+ test-and-build:
25
+ runs-on: ubuntu-latest
26
+
27
+ steps:
28
+ - uses: actions/checkout@v6
29
+
30
+ - name: Setup Node.js
31
+ uses: actions/setup-node@v4
32
+ with:
33
+ node-version: ${{ inputs.node_version }}
34
+ cache: "npm"
35
+
36
+ - name: Install dependencies
37
+ run: npm ci
38
+
39
+ - name: Run linting
40
+ run: npm run lint
41
+
42
+ - name: Run tests
43
+ run: npm test
44
+
45
+ - name: Zip coverage and upload to Quality Dashboard
46
+ if: always()
47
+ env:
48
+ QUALITY_DASHBOARD_URL: ${{ secrets.QUALITY_DASHBOARD_URL }}
49
+ QUALITY_DASHBOARD_TOKEN: ${{ secrets.QUALITY_DASHBOARD_TOKEN }}
50
+ run: |
51
+ PACKAGE_NAME=$(node -p "require('./package.json').name")
52
+ REPORT_KEY=$(echo "$PACKAGE_NAME" | sed 's/[^a-zA-Z0-9._:\-\/]/_/g')
53
+ REPORT_KEY="${REPORT_KEY}_coverage"
54
+
55
+ if [ -d coverage ]; then
56
+ if [ -z "$QUALITY_DASHBOARD_URL" ] || [ -z "$QUALITY_DASHBOARD_TOKEN" ]; then
57
+ echo "Quality Dashboard URL or token not set, skipping upload"
58
+ exit 0
59
+ fi
60
+ # Zip coverage contents at root level so the jest processor
61
+ # finds coverage-final.json / clover.xml directly
62
+ (cd coverage && zip -r "${{ runner.temp }}/coverage.zip" .)
63
+
64
+ META=$(jq -n \
65
+ --arg key "$REPORT_KEY" \
66
+ --arg pkg "$PACKAGE_NAME" \
67
+ '{
68
+ key: $key,
69
+ displayName: "Coverage: \($pkg)",
70
+ processor: "jest"
71
+ }')
72
+
73
+ echo "Uploading coverage: $REPORT_KEY"
74
+ HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
75
+ -X POST "$QUALITY_DASHBOARD_URL/api/reports/" \
76
+ -H "x-upload-token: $QUALITY_DASHBOARD_TOKEN" \
77
+ -F "meta=$META" \
78
+ -F "file=@${{ runner.temp }}/coverage.zip" \
79
+ --max-time 30)
80
+
81
+ if [ "$HTTP_CODE" = "201" ]; then
82
+ echo "\u2713 Coverage uploaded ($HTTP_CODE)"
83
+ else
84
+ echo "\u26a0 Upload returned HTTP $HTTP_CODE"
85
+ fi
86
+ else
87
+ echo "No coverage/ directory found, skipping upload"
88
+ fi
89
+
90
+ - name: Build package
91
+ run: npm run build
92
+
93
+ publish-release:
94
+ runs-on: ubuntu-latest
95
+ needs: test-and-build
96
+
97
+ steps:
98
+ - uses: actions/checkout@v6
99
+ with:
100
+ fetch-depth: 0
101
+
102
+ - name: Setup Node.js
103
+ uses: actions/setup-node@v4
104
+ with:
105
+ node-version: ${{ inputs.node_version }}
106
+ cache: "npm"
107
+ registry-url: "https://registry.npmjs.org"
108
+
109
+ - name: Install dependencies
110
+ run: npm ci
111
+
112
+ - name: Build package
113
+ run: npm run build
114
+
115
+ - name: Check if version changed
116
+ id: version-check
117
+ run: |
118
+ CURRENT_VERSION=$(node -p "require('./package.json').version")
119
+ echo "current-version=${CURRENT_VERSION}" >> $GITHUB_OUTPUT
120
+
121
+ if npm view ${{ inputs.npm_package_name }}@${CURRENT_VERSION} version &> /dev/null; then
122
+ echo "version-exists=true" >> $GITHUB_OUTPUT
123
+ echo "Version ${CURRENT_VERSION} already exists on npm"
124
+ else
125
+ echo "version-exists=false" >> $GITHUB_OUTPUT
126
+ echo "Version ${CURRENT_VERSION} is new, will publish"
127
+ fi
128
+
129
+ - name: Publish release package
130
+ if: steps.version-check.outputs.version-exists == 'false'
131
+ run: |
132
+ echo "Publishing version ${{ steps.version-check.outputs.current-version }}"
133
+ npm publish
134
+ env:
135
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -0,0 +1,153 @@
1
+ name: "Reusable: NPM PR"
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ node_version:
7
+ description: "Node.js version to use"
8
+ required: false
9
+ type: string
10
+ default: "18"
11
+ npm_package_name:
12
+ description: "NPM package name (e.g. @devopsplaybook.io/otel-utils)"
13
+ required: true
14
+ type: string
15
+ secrets:
16
+ NPM_TOKEN:
17
+ required: true
18
+ QUALITY_DASHBOARD_TOKEN:
19
+ required: false
20
+ QUALITY_DASHBOARD_URL:
21
+ required: false
22
+
23
+ jobs:
24
+ test-and-build:
25
+ runs-on: ubuntu-latest
26
+
27
+ steps:
28
+ - uses: actions/checkout@v6
29
+
30
+ - name: Setup Node.js
31
+ uses: actions/setup-node@v4
32
+ with:
33
+ node-version: ${{ inputs.node_version }}
34
+ cache: "npm"
35
+
36
+ - name: Install dependencies
37
+ run: npm ci
38
+
39
+ - name: Run linting
40
+ run: npm run lint
41
+
42
+ - name: Run tests
43
+ run: npm test
44
+
45
+ - name: Zip coverage and upload to Quality Dashboard
46
+ if: always()
47
+ env:
48
+ QUALITY_DASHBOARD_URL: ${{ secrets.QUALITY_DASHBOARD_URL }}
49
+ QUALITY_DASHBOARD_TOKEN: ${{ secrets.QUALITY_DASHBOARD_TOKEN }}
50
+ run: |
51
+ PACKAGE_NAME=$(node -p "require('./package.json').name")
52
+ REPORT_KEY=$(echo "$PACKAGE_NAME" | sed 's/[^a-zA-Z0-9._:\-\/]/_/g')
53
+ REPORT_KEY="${REPORT_KEY}_coverage"
54
+
55
+ if [ -d coverage ]; then
56
+ if [ -z "$QUALITY_DASHBOARD_URL" ] || [ -z "$QUALITY_DASHBOARD_TOKEN" ]; then
57
+ echo "Quality Dashboard URL or token not set, skipping upload"
58
+ exit 0
59
+ fi
60
+ # Zip coverage contents at root level so the jest processor
61
+ # finds coverage-final.json / clover.xml directly
62
+ (cd coverage && zip -r "${{ runner.temp }}/coverage.zip" .)
63
+
64
+ META=$(jq -n \
65
+ --arg key "$REPORT_KEY" \
66
+ --arg pkg "$PACKAGE_NAME" \
67
+ '{
68
+ key: $key,
69
+ displayName: "Coverage: \($pkg)",
70
+ processor: "jest"
71
+ }')
72
+
73
+ echo "Uploading coverage: $REPORT_KEY"
74
+ HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
75
+ -X POST "$QUALITY_DASHBOARD_URL/api/reports/" \
76
+ -H "x-upload-token: $QUALITY_DASHBOARD_TOKEN" \
77
+ -F "meta=$META" \
78
+ -F "file=@${{ runner.temp }}/coverage.zip" \
79
+ --max-time 30)
80
+
81
+ if [ "$HTTP_CODE" = "201" ]; then
82
+ echo "\u2713 Coverage uploaded ($HTTP_CODE)"
83
+ else
84
+ echo "\u26a0 Upload returned HTTP $HTTP_CODE"
85
+ fi
86
+ else
87
+ echo "No coverage/ directory found, skipping upload"
88
+ fi
89
+
90
+ - name: Build package
91
+ run: npm run build
92
+
93
+ publish-beta:
94
+ runs-on: ubuntu-latest
95
+ needs: test-and-build
96
+ if: github.event_name == 'pull_request'
97
+
98
+ steps:
99
+ - uses: actions/checkout@v6
100
+
101
+ - name: Setup Node.js
102
+ uses: actions/setup-node@v4
103
+ with:
104
+ node-version: ${{ inputs.node_version }}
105
+ cache: "npm"
106
+ registry-url: "https://registry.npmjs.org"
107
+
108
+ - name: Install dependencies
109
+ run: npm ci
110
+
111
+ - name: Build package
112
+ run: npm run build
113
+
114
+ - name: Generate beta version
115
+ id: beta-version
116
+ run: |
117
+ CURRENT_VERSION=$(node -p "require('./package.json').version")
118
+ PR_NUMBER=${{ github.event.pull_request.number }}
119
+ COMMIT_SHA=${GITHUB_SHA:0:7}
120
+ BETA_VERSION="${CURRENT_VERSION}-beta.${PR_NUMBER}.${COMMIT_SHA}"
121
+ echo "version=${BETA_VERSION}" >> $GITHUB_OUTPUT
122
+ echo "Beta version will be: ${BETA_VERSION}"
123
+
124
+ - name: Update package.json with beta version
125
+ run: |
126
+ npm version ${{ steps.beta-version.outputs.version }} --no-git-tag-version
127
+
128
+ - name: Publish beta package
129
+ run: npm publish --tag beta
130
+ env:
131
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
132
+
133
+ - name: Comment PR with beta version info
134
+ uses: actions/github-script@v7
135
+ with:
136
+ script: |
137
+ github.rest.issues.createComment({
138
+ issue_number: context.issue.number,
139
+ owner: context.repo.owner,
140
+ repo: context.repo.repo,
141
+ body: `🚀 **Beta version published!**
142
+
143
+ **Package**: \`${{ inputs.npm_package_name }}@${{ steps.beta-version.outputs.version }}\`
144
+
145
+ Install with:
146
+ \`\`\`bash
147
+ npm install ${{ inputs.npm_package_name }}@${{ steps.beta-version.outputs.version }}
148
+ # or
149
+ npm install ${{ inputs.npm_package_name }}@beta
150
+ \`\`\`
151
+
152
+ This beta version will be available for testing until the PR is merged.`
153
+ })
@@ -0,0 +1,92 @@
1
+ name: "Reusable: NPM Upgrade"
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ npm_services:
7
+ description: "JSON array of sub-folders containing NPM services to update"
8
+ required: true
9
+ type: string
10
+ pr_branch:
11
+ description: "Branch name for the upgrade PR (defaults to feature/YYYY.MM.DD-dependency-updates)"
12
+ required: false
13
+ type: string
14
+ default: ""
15
+
16
+ jobs:
17
+ npm-upgrade:
18
+ runs-on: ubuntu-latest
19
+ permissions:
20
+ contents: write
21
+ pull-requests: write
22
+ steps:
23
+ - uses: actions/checkout@v6
24
+
25
+ - name: Resolve branch name
26
+ id: branch
27
+ run: |
28
+ if [ -n "${{ inputs.pr_branch }}" ]; then
29
+ echo "name=${{ inputs.pr_branch }}" >> $GITHUB_OUTPUT
30
+ else
31
+ echo "name=feature/$(date +'%Y.%m.%d')-dependency-updates" >> $GITHUB_OUTPUT
32
+ fi
33
+
34
+ - name: Check for existing PR
35
+ id: check_pr
36
+ env:
37
+ GH_TOKEN: ${{ github.token }}
38
+ run: |
39
+ EXISTING_PR=$(gh pr list --state open --json number --jq 'length')
40
+ if [ "${EXISTING_PR}" -gt 0 ]; then
41
+ echo "An open PR already exists, skipping"
42
+ echo "skip=true" >> $GITHUB_OUTPUT
43
+ else
44
+ echo "skip=false" >> $GITHUB_OUTPUT
45
+ fi
46
+
47
+ - name: Update NPM dependencies
48
+ if: steps.check_pr.outputs.skip == 'false'
49
+ run: |
50
+ set -e
51
+ # Update root package
52
+ echo "Updating dependencies in root"
53
+ npx npm-check-updates -u
54
+ npm install
55
+ # Update sub-service packages
56
+ SERVICES='${{ inputs.npm_services }}'
57
+ for FOLDER in $(echo "${SERVICES}" | jq -r '.[]'); do
58
+ echo "Updating dependencies in ${FOLDER}"
59
+ cd "${FOLDER}"
60
+ npx npm-check-updates -u
61
+ npm install
62
+ cd "${GITHUB_WORKSPACE}"
63
+ done
64
+ if [ -n "$(git status --porcelain)" ]; then
65
+ echo "HAS_CHANGES=true" >> $GITHUB_ENV
66
+ fi
67
+
68
+ - name: Bump root package.json patch version
69
+ if: steps.check_pr.outputs.skip == 'false' && env.HAS_CHANGES == 'true'
70
+ run: |
71
+ set -e
72
+ CURRENT_VERSION=$(jq -r '.version' package.json)
73
+ NEW_VERSION=$(echo "${CURRENT_VERSION}" | awk -F. '{print $1"."$2"."$3+1}')
74
+ jq --arg v "${NEW_VERSION}" '.version = $v' package.json > package.json.tmp && mv package.json.tmp package.json
75
+ echo "Bumped root package.json version: ${CURRENT_VERSION} -> ${NEW_VERSION}"
76
+
77
+ - name: Create Pull Request
78
+ if: steps.check_pr.outputs.skip == 'false' && env.HAS_CHANGES == 'true'
79
+ env:
80
+ GH_TOKEN: ${{ github.token }}
81
+ run: |
82
+ git config user.name "github-actions[bot]"
83
+ git config user.email "github-actions[bot]@users.noreply.github.com"
84
+ git checkout -b "${{ steps.branch.outputs.name }}"
85
+ git add -A
86
+ git commit -m "chore: update NPM dependencies"
87
+ git push origin "${{ steps.branch.outputs.name }}"
88
+ gh pr create \
89
+ --title "chore: update NPM dependencies" \
90
+ --body "Automated NPM dependency update" \
91
+ --head "${{ steps.branch.outputs.name }}" \
92
+ --base main