@cbs-consulting/generator-btp 1.2.9 → 1.3.0
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/README.md +240 -61
- package/generators/app/__tests__/index.test.js +91 -4
- package/generators/app/index.js +11 -0
- package/generators/cap/__tests__/index.test.js +155 -7
- package/generators/cap/additions/package.json +1 -1
- package/generators/cap/additions/tsconfig.json +19 -0
- package/generators/cap/dependencies.json +1 -2
- package/generators/cap/index.js +273 -22
- package/generators/cap/templates/_.gitconfig.aliases +1 -0
- package/generators/cap/templates/_.gitignore +1 -0
- package/generators/cap/templates/jest.config.json +25 -0
- package/generators/cap/templates/srv/cat-service.ts +7 -0
- package/generators/cap/templates/test/CatalogService.test.ts +15 -0
- package/generators/devcontainer/__tests__/index.test.js +37 -0
- package/generators/devcontainer/index.js +22 -0
- package/generators/setup-azure-devops/__tests__/index.test.js +267 -0
- package/generators/setup-azure-devops/index.js +233 -0
- package/generators/setup-azure-devops/templates/scripts/setup-azure-devops/README.md +158 -0
- package/generators/setup-azure-devops/templates/scripts/setup-azure-devops/azure-devops.env +113 -0
- package/generators/setup-azure-devops/templates/scripts/setup-azure-devops/setup.sh +437 -0
- package/generators/ui5/index.js +7 -2
- package/package.json +2 -2
- package/utils/jsonFile.js +30 -1
- package/generators/cap/templates/base.tsconfig.json +0 -14
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
###############################################################################
|
|
4
|
+
# Azure DevOps Setup Script
|
|
5
|
+
#
|
|
6
|
+
# This script configures branch policies and creates a pipeline for your
|
|
7
|
+
# Azure DevOps repository.
|
|
8
|
+
#
|
|
9
|
+
# Prerequisites:
|
|
10
|
+
# - Azure CLI installed and authenticated (run 'az login --allow-no-subscriptions')
|
|
11
|
+
# - Azure DevOps extension installed (az extension add --name azure-devops)
|
|
12
|
+
# - Appropriate permissions in Azure DevOps project
|
|
13
|
+
# - Repository already created with main branch
|
|
14
|
+
#
|
|
15
|
+
# Usage:
|
|
16
|
+
# 1. Configure azure-devops.env with your values
|
|
17
|
+
# 2. Run: bash setup.sh
|
|
18
|
+
###############################################################################
|
|
19
|
+
|
|
20
|
+
set -e # Exit on error
|
|
21
|
+
|
|
22
|
+
# Colors for output
|
|
23
|
+
RED='\033[0;31m'
|
|
24
|
+
GREEN='\033[0;32m'
|
|
25
|
+
YELLOW='\033[1;33m'
|
|
26
|
+
BLUE='\033[0;34m'
|
|
27
|
+
NC='\033[0m' # No Color
|
|
28
|
+
|
|
29
|
+
# Get script directory
|
|
30
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
31
|
+
ENV_FILE="${SCRIPT_DIR}/azure-devops.env"
|
|
32
|
+
|
|
33
|
+
###############################################################################
|
|
34
|
+
# Functions
|
|
35
|
+
###############################################################################
|
|
36
|
+
|
|
37
|
+
log_info() {
|
|
38
|
+
echo -e "${BLUE}ℹ${NC} $1"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
log_success() {
|
|
42
|
+
echo -e "${GREEN}✓${NC} $1"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
log_warning() {
|
|
46
|
+
echo -e "${YELLOW}⚠${NC} $1"
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
log_error() {
|
|
50
|
+
echo -e "${RED}✗${NC} $1"
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
check_prerequisites() {
|
|
54
|
+
log_info "Checking prerequisites..."
|
|
55
|
+
|
|
56
|
+
# Check if Azure CLI is installed
|
|
57
|
+
if ! command -v az &> /dev/null; then
|
|
58
|
+
log_error "Azure CLI is not installed. Please install it first."
|
|
59
|
+
echo " Visit: https://docs.microsoft.com/cli/azure/install-azure-cli"
|
|
60
|
+
exit 1
|
|
61
|
+
fi
|
|
62
|
+
log_success "Azure CLI found"
|
|
63
|
+
|
|
64
|
+
# Check if Azure DevOps extension is installed
|
|
65
|
+
if ! az extension list --output tsv | grep -q "azure-devops"; then
|
|
66
|
+
log_warning "Azure DevOps extension not found. Installing..."
|
|
67
|
+
az extension add --name azure-devops
|
|
68
|
+
log_success "Azure DevOps extension installed"
|
|
69
|
+
else
|
|
70
|
+
log_success "Azure DevOps extension found"
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
# Check if logged in
|
|
74
|
+
if ! az account show &> /dev/null; then
|
|
75
|
+
log_error "Not logged in to Azure. Please run 'az login --allow-no-subscriptions' first."
|
|
76
|
+
exit 1
|
|
77
|
+
fi
|
|
78
|
+
log_success "Authenticated to Azure"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
load_config() {
|
|
82
|
+
log_info "Loading configuration from ${ENV_FILE}..."
|
|
83
|
+
|
|
84
|
+
if [ ! -f "${ENV_FILE}" ]; then
|
|
85
|
+
log_error "Configuration file not found: ${ENV_FILE}"
|
|
86
|
+
log_error "Please create azure-devops.env from the template and configure it."
|
|
87
|
+
exit 1
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
# Source the env file
|
|
91
|
+
# shellcheck disable=SC1090
|
|
92
|
+
source "${ENV_FILE}"
|
|
93
|
+
|
|
94
|
+
# Validate required variables
|
|
95
|
+
if [ -z "${AZURE_DEVOPS_ORG_URL}" ]; then
|
|
96
|
+
log_error "AZURE_DEVOPS_ORG_URL is not set in ${ENV_FILE}"
|
|
97
|
+
exit 1
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
if [ -z "${AZURE_PROJECT_NAME}" ]; then
|
|
101
|
+
log_error "AZURE_PROJECT_NAME is not set in ${ENV_FILE}"
|
|
102
|
+
exit 1
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
if [ -z "${REPO_NAME}" ]; then
|
|
106
|
+
log_error "REPO_NAME is not set in ${ENV_FILE}"
|
|
107
|
+
exit 1
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
log_success "Configuration loaded successfully"
|
|
111
|
+
log_info " Organization: ${AZURE_DEVOPS_ORG_URL}"
|
|
112
|
+
log_info " Project: ${AZURE_PROJECT_NAME}"
|
|
113
|
+
log_info " Repository: ${REPO_NAME}"
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
configure_azure_devops_defaults() {
|
|
117
|
+
log_info "Configuring Azure DevOps CLI defaults..."
|
|
118
|
+
az devops configure --defaults organization="${AZURE_DEVOPS_ORG_URL}" project="${AZURE_PROJECT_NAME}"
|
|
119
|
+
log_success "Defaults configured"
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
get_repo_id() {
|
|
123
|
+
log_info "Getting repository ID..."
|
|
124
|
+
REPO_ID=$(az repos show --repository "${REPO_NAME}" --query id --output tsv)
|
|
125
|
+
if [ -z "${REPO_ID}" ]; then
|
|
126
|
+
log_error "Failed to get repository ID. Does the repository '${REPO_NAME}' exist?"
|
|
127
|
+
exit 1
|
|
128
|
+
fi
|
|
129
|
+
log_success "Repository ID: ${REPO_ID}"
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
check_main_branch_exists() {
|
|
133
|
+
log_info "Checking if '${MAIN_BRANCH}' branch exists..."
|
|
134
|
+
|
|
135
|
+
if ! az repos ref list --repository "${REPO_NAME}" --query "[?name=='refs/heads/${MAIN_BRANCH}'].name" --output tsv | grep -q "refs/heads/${MAIN_BRANCH}"; then
|
|
136
|
+
log_warning "The '${MAIN_BRANCH}' branch does not exist in the repository."
|
|
137
|
+
log_info "This usually means the repository is empty with no initial commit."
|
|
138
|
+
echo ""
|
|
139
|
+
|
|
140
|
+
# Ask user if they want to create initial commit
|
|
141
|
+
read -p "$(echo -e ${BLUE}?${NC}) Would you like to create an initial commit automatically? (y/n): " -n 1 -r
|
|
142
|
+
echo ""
|
|
143
|
+
|
|
144
|
+
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
145
|
+
create_initial_commit
|
|
146
|
+
else
|
|
147
|
+
echo ""
|
|
148
|
+
log_info "To manually create an initial commit:"
|
|
149
|
+
echo " 1. Clone the repository: git clone ${AZURE_DEVOPS_ORG_URL}/${AZURE_PROJECT_NAME}/_git/${REPO_NAME}"
|
|
150
|
+
echo " 2. Create an initial commit:"
|
|
151
|
+
echo " echo '# ${REPO_NAME}' > README.md"
|
|
152
|
+
echo " git add README.md"
|
|
153
|
+
echo " git commit -m 'Initial commit'"
|
|
154
|
+
echo " git push -u origin ${MAIN_BRANCH}"
|
|
155
|
+
echo " 3. Run this setup script again"
|
|
156
|
+
echo ""
|
|
157
|
+
exit 1
|
|
158
|
+
fi
|
|
159
|
+
else
|
|
160
|
+
log_success "'${MAIN_BRANCH}' branch exists"
|
|
161
|
+
fi
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
create_initial_commit() {
|
|
165
|
+
log_info "Creating initial commit..."
|
|
166
|
+
|
|
167
|
+
# Check if git is installed
|
|
168
|
+
if ! command -v git &> /dev/null; then
|
|
169
|
+
log_error "Git is not installed. Cannot create initial commit automatically."
|
|
170
|
+
exit 1
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
# Create a temporary directory
|
|
174
|
+
TEMP_DIR=$(mktemp -d)
|
|
175
|
+
log_info "Using temporary directory: ${TEMP_DIR}"
|
|
176
|
+
|
|
177
|
+
# Clone the empty repository
|
|
178
|
+
log_info "Cloning repository..."
|
|
179
|
+
REPO_URL="${AZURE_DEVOPS_ORG_URL}/${AZURE_PROJECT_NAME}/_git/${REPO_NAME}"
|
|
180
|
+
|
|
181
|
+
if ! git clone "${REPO_URL}" "${TEMP_DIR}/${REPO_NAME}" 2>/dev/null; then
|
|
182
|
+
log_error "Failed to clone repository. Please check your credentials and permissions."
|
|
183
|
+
rm -rf "${TEMP_DIR}"
|
|
184
|
+
exit 1
|
|
185
|
+
fi
|
|
186
|
+
|
|
187
|
+
cd "${TEMP_DIR}/${REPO_NAME}"
|
|
188
|
+
|
|
189
|
+
# Configure git user if not set
|
|
190
|
+
if [ -z "$(git config user.email)" ]; then
|
|
191
|
+
git config user.email "azure-devops-setup@example.com"
|
|
192
|
+
git config user.name "Azure DevOps Setup Script"
|
|
193
|
+
fi
|
|
194
|
+
|
|
195
|
+
# Create README.md
|
|
196
|
+
log_info "Creating README.md..."
|
|
197
|
+
cat > README.md << EOF
|
|
198
|
+
# ${REPO_NAME}
|
|
199
|
+
|
|
200
|
+
This repository was initialized automatically by the Azure DevOps setup script.
|
|
201
|
+
|
|
202
|
+
## Getting Started
|
|
203
|
+
|
|
204
|
+
Add your project documentation here.
|
|
205
|
+
EOF
|
|
206
|
+
|
|
207
|
+
# Commit and push
|
|
208
|
+
log_info "Committing and pushing to '${MAIN_BRANCH}'..."
|
|
209
|
+
git add README.md
|
|
210
|
+
git commit -m "Initial commit"
|
|
211
|
+
git push -u origin "${MAIN_BRANCH}"
|
|
212
|
+
|
|
213
|
+
# Clean up
|
|
214
|
+
cd - > /dev/null
|
|
215
|
+
rm -rf "${TEMP_DIR}"
|
|
216
|
+
|
|
217
|
+
log_success "Initial commit created and pushed to '${MAIN_BRANCH}'"
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
ensure_branch_exists() {
|
|
221
|
+
local branch_name=$1
|
|
222
|
+
log_info "Checking if branch '${branch_name}' exists..."
|
|
223
|
+
|
|
224
|
+
if az repos ref list --repository "${REPO_NAME}" --query "[?name=='refs/heads/${branch_name}'].name" --output tsv | grep -q "refs/heads/${branch_name}"; then
|
|
225
|
+
log_success "Branch '${branch_name}' exists"
|
|
226
|
+
else
|
|
227
|
+
log_warning "Branch '${branch_name}' does not exist"
|
|
228
|
+
log_info "Creating branch '${branch_name}' from main..."
|
|
229
|
+
|
|
230
|
+
# Get the commit SHA of the main branch
|
|
231
|
+
MAIN_COMMIT=$(az repos ref list --repository "${REPO_NAME}" --query "[?name=='refs/heads/${MAIN_BRANCH}'].objectId" --output tsv)
|
|
232
|
+
|
|
233
|
+
if [ -z "${MAIN_COMMIT}" ]; then
|
|
234
|
+
log_error "Failed to get commit SHA for '${MAIN_BRANCH}' branch"
|
|
235
|
+
exit 1
|
|
236
|
+
fi
|
|
237
|
+
|
|
238
|
+
az repos ref create --name "refs/heads/${branch_name}" --repository "${REPO_NAME}" --object-id "${MAIN_COMMIT}"
|
|
239
|
+
log_success "Branch '${branch_name}' created"
|
|
240
|
+
fi
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
set_default_branch() {
|
|
244
|
+
if [ "${SET_DEVELOPMENT_BRANCH_AS_DEFAULT}" = true ]; then
|
|
245
|
+
log_info "Setting '${DEV_BRANCH}' as the default branch..."
|
|
246
|
+
az repos update --repository "${REPO_NAME}" --default-branch "${DEV_BRANCH}"
|
|
247
|
+
log_success "'${DEV_BRANCH}' is now the default branch"
|
|
248
|
+
else
|
|
249
|
+
log_info "Keeping '${MAIN_BRANCH}' as the default branch"
|
|
250
|
+
fi
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
configure_main_branch_policies() {
|
|
254
|
+
log_info "Configuring branch policies for '${MAIN_BRANCH}'..."
|
|
255
|
+
|
|
256
|
+
# Minimum number of reviewers policy
|
|
257
|
+
log_info " Setting minimum approver count policy..."
|
|
258
|
+
az repos policy approver-count create \
|
|
259
|
+
--blocking true \
|
|
260
|
+
--enabled true \
|
|
261
|
+
--creator-vote-counts false \
|
|
262
|
+
--allow-downvotes false \
|
|
263
|
+
--reset-on-source-push "${MAIN_RESET_ON_SOURCE_PUSH}" \
|
|
264
|
+
--branch "${MAIN_BRANCH}" \
|
|
265
|
+
--minimum-approver-count "${MIN_REVIEWERS}" \
|
|
266
|
+
--repository-id "${REPO_ID}" \
|
|
267
|
+
--output none 2>/dev/null || log_warning "Approver count policy may already exist"
|
|
268
|
+
|
|
269
|
+
# Build validation policy
|
|
270
|
+
log_info " Setting build validation policy..."
|
|
271
|
+
|
|
272
|
+
# Check if build validation policy already exists for this branch and build definition
|
|
273
|
+
EXISTING_BUILD_POLICY=$(az repos policy list --repository-id "${REPO_ID}" --branch "${MAIN_BRANCH}" \
|
|
274
|
+
--query "[?type.displayName=='Build' && settings.buildDefinitionId==${BUILD_DEFINITION_ID}].id" \
|
|
275
|
+
--output tsv 2>/dev/null)
|
|
276
|
+
|
|
277
|
+
if [ -n "${EXISTING_BUILD_POLICY}" ]; then
|
|
278
|
+
log_warning "Build validation policy already exists for '${MAIN_BRANCH}' (Policy ID: ${EXISTING_BUILD_POLICY})"
|
|
279
|
+
else
|
|
280
|
+
az repos policy build create \
|
|
281
|
+
--blocking true \
|
|
282
|
+
--enabled true \
|
|
283
|
+
--manual-queue-only false \
|
|
284
|
+
--queue-on-source-update-only true \
|
|
285
|
+
--valid-duration 0 \
|
|
286
|
+
--branch "${MAIN_BRANCH}" \
|
|
287
|
+
--build-definition-id "${BUILD_DEFINITION_ID}" \
|
|
288
|
+
--display-name "PR Build Validation - ${MAIN_BRANCH}" \
|
|
289
|
+
--repository-id "${REPO_ID}" \
|
|
290
|
+
--output none
|
|
291
|
+
log_success "Build validation policy created"
|
|
292
|
+
fi
|
|
293
|
+
|
|
294
|
+
# Merge type restriction policy
|
|
295
|
+
log_info " Setting merge type restriction policy..."
|
|
296
|
+
az repos policy merge-strategy create \
|
|
297
|
+
--blocking true \
|
|
298
|
+
--branch "${MAIN_BRANCH}" \
|
|
299
|
+
--enabled true \
|
|
300
|
+
--repository-id "${REPO_ID}" \
|
|
301
|
+
--allow-no-fast-forward "${MAIN_ALLOW_NO_FAST_FORWARD}" \
|
|
302
|
+
--allow-rebase "${MAIN_ALLOW_REBASE}" \
|
|
303
|
+
--allow-rebase-merge "${MAIN_ALLOW_REBASE_MERGE}" \
|
|
304
|
+
--allow-squash "${MAIN_ALLOW_SQUASH_MERGE}" \
|
|
305
|
+
--output none 2>/dev/null || log_warning "Merge type policy may already exist"
|
|
306
|
+
|
|
307
|
+
log_success "Main branch policies configured"
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
configure_dev_branch_policies() {
|
|
311
|
+
log_info "Configuring branch policies for '${DEV_BRANCH}'..."
|
|
312
|
+
|
|
313
|
+
# Build validation policy
|
|
314
|
+
log_info " Setting build validation policy..."
|
|
315
|
+
|
|
316
|
+
# Check if build validation policy already exists for this branch and build definition
|
|
317
|
+
EXISTING_BUILD_POLICY=$(az repos policy list --repository-id "${REPO_ID}" --branch "${DEV_BRANCH}" \
|
|
318
|
+
--query "[?type.displayName=='Build' && settings.buildDefinitionId==${BUILD_DEFINITION_ID}].id" \
|
|
319
|
+
--output tsv 2>/dev/null)
|
|
320
|
+
|
|
321
|
+
if [ -n "${EXISTING_BUILD_POLICY}" ]; then
|
|
322
|
+
log_warning "Build validation policy already exists for '${DEV_BRANCH}' (Policy ID: ${EXISTING_BUILD_POLICY})"
|
|
323
|
+
else
|
|
324
|
+
az repos policy build create \
|
|
325
|
+
--blocking true \
|
|
326
|
+
--enabled true \
|
|
327
|
+
--manual-queue-only false \
|
|
328
|
+
--queue-on-source-update-only true \
|
|
329
|
+
--valid-duration 0 \
|
|
330
|
+
--branch "${DEV_BRANCH}" \
|
|
331
|
+
--build-definition-id "${BUILD_DEFINITION_ID}" \
|
|
332
|
+
--display-name "PR Build Validation - ${DEV_BRANCH}" \
|
|
333
|
+
--repository-id "${REPO_ID}" \
|
|
334
|
+
--output none
|
|
335
|
+
log_success "Build validation policy created"
|
|
336
|
+
fi
|
|
337
|
+
|
|
338
|
+
# Merge type restriction policy for development branch
|
|
339
|
+
log_info " Setting merge type restriction policy..."
|
|
340
|
+
az repos policy merge-strategy create \
|
|
341
|
+
--blocking true \
|
|
342
|
+
--branch "${DEV_BRANCH}" \
|
|
343
|
+
--enabled true \
|
|
344
|
+
--repository-id "${REPO_ID}" \
|
|
345
|
+
--allow-no-fast-forward "${DEV_ALLOW_NO_FAST_FORWARD}" \
|
|
346
|
+
--allow-rebase "${DEV_ALLOW_REBASE}" \
|
|
347
|
+
--allow-rebase-merge "${DEV_ALLOW_REBASE_MERGE}" \
|
|
348
|
+
--allow-squash "${DEV_ALLOW_SQUASH_MERGE}" \
|
|
349
|
+
--output none 2>/dev/null || log_warning "Merge type policy may already exist"
|
|
350
|
+
|
|
351
|
+
log_success "Development branch policies configured"
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
create_or_get_pipeline() {
|
|
355
|
+
log_info "Setting up pipeline '${PIPELINE_NAME}'..."
|
|
356
|
+
|
|
357
|
+
# Check if pipeline already exists
|
|
358
|
+
if az pipelines list --query "[?name=='${PIPELINE_NAME}'].id" --output tsv | grep -q .; then
|
|
359
|
+
BUILD_DEFINITION_ID=$(az pipelines list --query "[?name=='${PIPELINE_NAME}'].id" --output tsv)
|
|
360
|
+
log_warning "Pipeline '${PIPELINE_NAME}' already exists. Using existing pipeline."
|
|
361
|
+
log_info " Pipeline ID: ${BUILD_DEFINITION_ID}"
|
|
362
|
+
else
|
|
363
|
+
# Create pipeline (tfsgit = Azure Repos Git)
|
|
364
|
+
log_info "Creating pipeline..."
|
|
365
|
+
BUILD_DEFINITION_ID=$(az pipelines create \
|
|
366
|
+
--name "${PIPELINE_NAME}" \
|
|
367
|
+
--repository "${REPO_NAME}" \
|
|
368
|
+
--repository-type tfsgit \
|
|
369
|
+
--branch "${MAIN_BRANCH}" \
|
|
370
|
+
--yml-path "${PIPELINE_YAML_PATH}" \
|
|
371
|
+
--skip-first-run \
|
|
372
|
+
--query id \
|
|
373
|
+
--output tsv)
|
|
374
|
+
|
|
375
|
+
log_success "Pipeline '${PIPELINE_NAME}' created"
|
|
376
|
+
log_info " Pipeline ID: ${BUILD_DEFINITION_ID}"
|
|
377
|
+
fi
|
|
378
|
+
|
|
379
|
+
if [ -z "${BUILD_DEFINITION_ID}" ]; then
|
|
380
|
+
log_error "Failed to get pipeline ID"
|
|
381
|
+
exit 1
|
|
382
|
+
fi
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
###############################################################################
|
|
386
|
+
# Main execution
|
|
387
|
+
###############################################################################
|
|
388
|
+
|
|
389
|
+
main() {
|
|
390
|
+
echo ""
|
|
391
|
+
echo "╔════════════════════════════════════════════════════════════════╗"
|
|
392
|
+
echo "║ Azure DevOps Repository Setup Script ║"
|
|
393
|
+
echo "╚════════════════════════════════════════════════════════════════╝"
|
|
394
|
+
echo ""
|
|
395
|
+
|
|
396
|
+
check_prerequisites
|
|
397
|
+
load_config
|
|
398
|
+
configure_azure_devops_defaults
|
|
399
|
+
get_repo_id
|
|
400
|
+
check_main_branch_exists
|
|
401
|
+
|
|
402
|
+
# Ensure development branch exists
|
|
403
|
+
ensure_branch_exists "${DEV_BRANCH}"
|
|
404
|
+
|
|
405
|
+
# Set default branch
|
|
406
|
+
set_default_branch
|
|
407
|
+
|
|
408
|
+
# Create or get pipeline (needed for build validation policies)
|
|
409
|
+
create_or_get_pipeline
|
|
410
|
+
|
|
411
|
+
# Configure branch policies (including build validation)
|
|
412
|
+
configure_main_branch_policies
|
|
413
|
+
configure_dev_branch_policies
|
|
414
|
+
|
|
415
|
+
echo ""
|
|
416
|
+
log_success "Azure DevOps setup completed successfully!"
|
|
417
|
+
echo ""
|
|
418
|
+
echo "Summary:"
|
|
419
|
+
echo " • Default branch: ${DEV_BRANCH}"
|
|
420
|
+
echo " • Main branch policies: Min ${MIN_REVIEWERS} reviewer(s), build validation, merge restrictions"
|
|
421
|
+
echo " • Development branch policies: Build validation, merge restrictions"
|
|
422
|
+
echo " • Pipeline: ${PIPELINE_NAME} (ID: ${BUILD_DEFINITION_ID})"
|
|
423
|
+
echo ""
|
|
424
|
+
echo "Links:"
|
|
425
|
+
echo " • Pipeline: ${AZURE_DEVOPS_ORG_URL}/${AZURE_PROJECT_NAME}/_build?definitionId=${BUILD_DEFINITION_ID}"
|
|
426
|
+
echo " • Main branch policies: ${AZURE_DEVOPS_ORG_URL}/${AZURE_PROJECT_NAME}/_settings/repositories?repo=${REPO_ID}&_a=policiesMid&refs=refs%2Fheads%2F${MAIN_BRANCH}"
|
|
427
|
+
echo " • Dev branch policies: ${AZURE_DEVOPS_ORG_URL}/${AZURE_PROJECT_NAME}/_settings/repositories?repo=${REPO_ID}&_a=policiesMid&refs=refs%2Fheads%2F${DEV_BRANCH}"
|
|
428
|
+
echo ""
|
|
429
|
+
log_info "Next steps:"
|
|
430
|
+
echo " 1. Review the policies in Azure DevOps portal"
|
|
431
|
+
echo " 2. Configure additional settings as needed"
|
|
432
|
+
echo " 3. Start pushing your code and creating pull requests"
|
|
433
|
+
echo ""
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
# Run main function
|
|
437
|
+
main "$@"
|
package/generators/ui5/index.js
CHANGED
|
@@ -4,7 +4,12 @@ import { join, dirname } from "node:path";
|
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import chalk from "chalk";
|
|
6
6
|
import mergewith from "lodash.mergewith";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
readJsonC,
|
|
9
|
+
readJsonCSafe,
|
|
10
|
+
mergeArray,
|
|
11
|
+
sortPackageJson,
|
|
12
|
+
} from "../../utils/jsonFile.js";
|
|
8
13
|
|
|
9
14
|
const __filename = fileURLToPath(import.meta.url);
|
|
10
15
|
const __dirname = dirname(__filename);
|
|
@@ -62,7 +67,7 @@ export default class extends Generator {
|
|
|
62
67
|
const destPkg = readJsonCSafe(this, destPkgPath, {});
|
|
63
68
|
const addPkg = readJsonC(srcPkgPath, {});
|
|
64
69
|
const mergedPkg = mergewith({}, destPkg, addPkg, mergeArray);
|
|
65
|
-
this.fs.writeJSON(destPkgPath, mergedPkg);
|
|
70
|
+
this.fs.writeJSON(destPkgPath, sortPackageJson(mergedPkg));
|
|
66
71
|
|
|
67
72
|
// tsconfig.json - handle rootDir sentinel and union rootDirs
|
|
68
73
|
const destTsPath = join(appDir, "tsconfig.json");
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cbs-consulting/generator-btp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "Yeoman generator for bootstrapping CAP/UI5 projects with TypeScript, ESLint, and other essential configurations",
|
|
5
|
+
"description": "CBS Best Practice Generator - Yeoman generator for bootstrapping CAP/UI5 projects with TypeScript, ESLint, and other essential configurations",
|
|
6
6
|
"main": "generators/app/index.js",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"link": "npm link",
|
package/utils/jsonFile.js
CHANGED
|
@@ -34,4 +34,33 @@ function mergeArray(objValue, srcValue) {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
const PKG_KEY_ORDER = [
|
|
38
|
+
"name",
|
|
39
|
+
"version",
|
|
40
|
+
"description",
|
|
41
|
+
"main",
|
|
42
|
+
"module",
|
|
43
|
+
"scripts",
|
|
44
|
+
"keywords",
|
|
45
|
+
"author",
|
|
46
|
+
"license",
|
|
47
|
+
"dependencies",
|
|
48
|
+
"devDependencies",
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
function sortPackageJson(pkg) {
|
|
52
|
+
const sorted = {};
|
|
53
|
+
for (const key of PKG_KEY_ORDER) {
|
|
54
|
+
if (Object.prototype.hasOwnProperty.call(pkg, key)) {
|
|
55
|
+
sorted[key] = pkg[key];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
for (const key of Object.keys(pkg)) {
|
|
59
|
+
if (!PKG_KEY_ORDER.includes(key)) {
|
|
60
|
+
sorted[key] = pkg[key];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return sorted;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { readJsonC, readJsonCSafe, mergeArray, sortPackageJson };
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"noUnusedLocals": true,
|
|
4
|
-
"noUnusedParameters": true,
|
|
5
|
-
"allowUnusedLabels": false,
|
|
6
|
-
"allowUnreachableCode": false,
|
|
7
|
-
"noImplicitOverride": true,
|
|
8
|
-
"noImplicitReturns": true,
|
|
9
|
-
"noPropertyAccessFromIndexSignature": true,
|
|
10
|
-
"noFallthroughCasesInSwitch": true,
|
|
11
|
-
"forceConsistentCasingInFileNames": true,
|
|
12
|
-
"exactOptionalPropertyTypes": true
|
|
13
|
-
}
|
|
14
|
-
}
|