Skip to content

Commit 0c8be00

Browse files
committed
Update CDS extractor unit tests actions workflow
Updates the `CodeQL - Run Unit Tests (javascript` actions workflow to align with recent changes to CDS extractor behavior. Adds the `cds-compilation-for-actions.test.sh` script as well as a note in the CDS extractor's `README.md` documentation in order to encourage improved synchronization between actual CDS extractor behavior versus what the unit tests actions workflow actually compiles.
1 parent c5c35d7 commit 0c8be00

File tree

3 files changed

+229
-39
lines changed

3 files changed

+229
-39
lines changed

.github/workflows/run-codeql-unit-tests-javascript.yml

Lines changed: 19 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -77,48 +77,28 @@ jobs:
7777
run: |
7878
qlt query run install-packs
7979
80-
- name: Ensure presence of cds shell command
81-
run: |
82-
if ! command -v cds &> /dev/null
83-
then
84-
## Workaround for https://github.tools.sap/cap/issues/issues/17840
85-
npm install -g @sap/cds-dk@8.6.1
86-
fi
80+
- name: Setup Node.js for CDS compilation
81+
uses: actions/setup-node@v4
82+
with:
83+
node-version: '18'
84+
cache: 'npm'
8785

88-
# Compile .cds files to .cds.json files.
86+
- name: Verify Node.js and npm tools
87+
run: |
88+
echo "Node.js version: $(node --version)"
89+
echo "npm version: $(npm --version)"
90+
echo "npx version: $(npx --version)"
91+
# Verify npx can access @sap/cds-dk without installing globally
92+
echo "Testing npx access to @sap/cds-dk..."
93+
npx --yes --package @sap/cds-dk@latest cds --version || echo "CDS will be installed per-project as needed"
94+
95+
# Compile .cds files to .cds.json files using the dedicated test script
8996
- name: Compile CAP CDS files
9097
run: |
91-
for test_dir in $(find . -type f -name '*.expected' -exec dirname {} \;);
92-
do
93-
# The CDS compiler produces locations relative to the working directory
94-
# so we switch to the test directory before running the compiler.
95-
pushd $test_dir
96-
for cds_file in $(find . -type f \( -iname '*.cds' \) -print)
97-
do
98-
echo "I am compiling $cds_file"
99-
_out_path="${cds_file}.json"
100-
cds compile $cds_file \
101-
--locations \
102-
--to json \
103-
--dest "$_out_path" \
104-
2> "$cds_file.err"
105-
# Check if the output is a regular file or a (sub)directory, where
106-
# files generated in an output directory will need to have the file
107-
# extension changed from '.json' to '.cds.json', but we don't need
108-
# to rename anything if the cds compiler just generated a single
109-
# '.cds.json' file.
110-
if [ -d "$_out_path" ]
111-
then
112-
for json_file in $(find "$_out_path" -type f \( -iname '*.json' \) -print)
113-
do
114-
_new_path="${json_file%.json}.cds.json"
115-
echo "Renaming CDS compiler generated JSON file $json_file to $_new_path"
116-
mv "$json_file" "$_new_path"
117-
done
118-
fi
119-
done
120-
popd
121-
done
98+
# Use the dedicated CDS compilation script that includes proper version resolution
99+
# This script follows the same logic as the CDS extractor's resolveCdsVersions function
100+
chmod +x extractors/cds/tools/test/cds-compilation-for-actions.test.sh
101+
./extractors/cds/tools/test/cds-compilation-for-actions.test.sh
122102
123103
- name: Run test suites
124104
id: run-test-suites

extractors/cds/tools/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ node dist/cds-extractor.js /path/to/source/root
6363

6464
## Development
6565

66+
> **⚠️ IMPORTANT NOTE**: Any changes to the CDS extractor's compilation task behavior (including how and where `cds compile` commands are executed, project detection logic, or output file generation patterns) **MUST** be reflected in the `extractors/cds/tools/test/cds-compilation-for-actions.test.sh` script. The `.github/workflows/run-codeql-unit-tests-javascript.yml` workflow executes this script during the "Compile CAP CDS files" step to simulate the CDS extractor's compilation process for unit tests. If the script and extractor implementations diverge, the `CodeQL - Run Unit Tests (javascript)` workflow will fail on PRs, causing status check failures. Always review and update the test script when modifying compilation behavior to maintain consistency between local testing and CI/CD environments.
67+
6668
### Project Structure
6769

6870
```text
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
#!/bin/bash
2+
3+
# Temporary test script for CDS compilation logic from GitHub Actions workflow
4+
# Usage: ./cds-compilation-for-actions.test.sh
5+
6+
set -e
7+
8+
# Base directory to scan (relative to project root)
9+
BASE_DIR="javascript/frameworks/cap/test/queries"
10+
11+
# Navigate to project root directory (4 levels up from extractors/cds/tools/test/)
12+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../../../" && pwd)"
14+
cd "$PROJECT_ROOT"
15+
16+
# Verify base directory exists
17+
if [ ! -d "$BASE_DIR" ]; then
18+
echo "Error: Base directory '$BASE_DIR' does not exist"
19+
echo "Current working directory: $(pwd)"
20+
echo "Expected path: $PROJECT_ROOT/$BASE_DIR"
21+
exit 1
22+
fi
23+
24+
echo "Testing CDS compilation logic from GitHub Actions workflow"
25+
echo "Project root: $PROJECT_ROOT"
26+
echo "Base directory: $BASE_DIR"
27+
echo "Working from: $(pwd)"
28+
echo ""
29+
30+
# Function to resolve CDS-DK version based on package.json
31+
# Follows the same logic as resolveCdsVersions in command.ts
32+
resolve_cds_dk_version() {
33+
local package_json_path="$1"
34+
local minimum_version=8
35+
36+
if [ ! -f "$package_json_path" ]; then
37+
echo "^$minimum_version"
38+
return
39+
fi
40+
41+
# Extract @sap/cds and @sap/cds-dk versions from package.json using grep and sed
42+
local cds_version=""
43+
local cds_dk_version=""
44+
45+
if grep -q '"@sap/cds"' "$package_json_path"; then
46+
cds_version=$(grep '"@sap/cds"' "$package_json_path" | sed -E 's/.*"@sap\/cds": "([^"]+)".*/\1/')
47+
fi
48+
49+
if grep -q '"@sap/cds-dk"' "$package_json_path"; then
50+
cds_dk_version=$(grep '"@sap/cds-dk"' "$package_json_path" | sed -E 's/.*"@sap\/cds-dk": "([^"]+)".*/\1/')
51+
fi
52+
53+
local preferred_dk_version=""
54+
55+
if [ -n "$cds_dk_version" ]; then
56+
# Use explicit @sap/cds-dk version if available, but enforce minimum
57+
preferred_dk_version=$(enforce_minimum_version "$cds_dk_version" "$minimum_version")
58+
elif [ -n "$cds_version" ]; then
59+
# Derive compatible @sap/cds-dk version from @sap/cds version
60+
preferred_dk_version=$(derive_compatible_version "$cds_version" "$minimum_version")
61+
else
62+
# No version information found, use minimum
63+
preferred_dk_version="^$minimum_version"
64+
fi
65+
66+
echo "$preferred_dk_version"
67+
}
68+
69+
# Function to enforce minimum version requirement
70+
enforce_minimum_version() {
71+
local version="$1"
72+
local minimum_version="$2"
73+
74+
# Extract major version number (handle ^, ~, and plain numbers)
75+
local major_version=$(echo "$version" | sed -E 's/^[\^~]?([0-9]+).*/\1/')
76+
77+
if [[ "$major_version" =~ ^[0-9]+$ ]]; then
78+
if [ "$major_version" -lt "$minimum_version" ]; then
79+
echo "^$minimum_version"
80+
else
81+
echo "$version"
82+
fi
83+
else
84+
echo "$version"
85+
fi
86+
}
87+
88+
# Function to derive compatible @sap/cds-dk version from @sap/cds version
89+
derive_compatible_version() {
90+
local cds_version="$1"
91+
local minimum_version="$2"
92+
93+
# Extract major version and use same range
94+
local major_version=$(echo "$cds_version" | sed -E 's/^[\^~]?([0-9]+).*/\1/')
95+
96+
if [[ "$major_version" =~ ^[0-9]+$ ]]; then
97+
local derived_version="^$major_version"
98+
# Apply minimum version enforcement
99+
enforce_minimum_version "$derived_version" "$minimum_version"
100+
else
101+
# Fallback if version can't be parsed - use minimum
102+
echo "^$minimum_version"
103+
fi
104+
}
105+
106+
# Function to create relative path (macOS compatible)
107+
get_relative_path() {
108+
local target="$1"
109+
local base="$2"
110+
111+
# Use Python to calculate relative path (works on both macOS and Linux)
112+
python3 -c "import os.path; print(os.path.relpath('$target', '$base'))" 2>/dev/null || echo "$target"
113+
}
114+
115+
# Clean up any existing model.cds.json files first
116+
echo "Cleaning up existing model.cds.json files..."
117+
find "$BASE_DIR" -name "model.cds.json" -type f -delete
118+
echo "Cleanup completed."
119+
echo ""
120+
121+
# Array to collect generated model.cds.json files
122+
GENERATED_FILES=()
123+
124+
# Find test directories (those containing .expected files)
125+
echo "Scanning for test directories..."
126+
for test_dir in $(find "$BASE_DIR" -type f -name '*.expected' -exec dirname {} \;);
127+
do
128+
echo "Processing test directory: $test_dir"
129+
130+
# Change to test directory
131+
pushd "$test_dir" > /dev/null
132+
133+
# Generate a single model.cds.json file per project directory,
134+
# aligning with the CDS extractor's standardized compilation behavior.
135+
echo " Compiling CDS project in directory: $(pwd)"
136+
137+
# Resolve the appropriate @sap/cds-dk version for this project
138+
local_package_json="$(pwd)/package.json"
139+
preferred_dk_version=$(resolve_cds_dk_version "$local_package_json")
140+
echo " Resolved @sap/cds-dk version: $preferred_dk_version"
141+
142+
# Determine compilation targets using simplified logic from CDS extractor
143+
COMPILE_TARGETS=""
144+
145+
# Rule 1. index.cds if the test_dir directly contains an index.cds file (highest priority)
146+
if [ -f "index.cds" ]; then
147+
COMPILE_TARGETS="index.cds"
148+
echo " Using index.cds as compilation target"
149+
else
150+
# Rule 2. app/ db/ srv/ if there are no .cds files directly in the test_dir
151+
ROOT_CDS_FILES=$(find . -maxdepth 1 -type f -name '*.cds' | wc -l)
152+
if [ "$ROOT_CDS_FILES" -eq 0 ]; then
153+
# No root CDS files, use CAP directories
154+
COMPILE_TARGETS="app db srv"
155+
echo " Using CAP directories as compilation targets: app db srv"
156+
else
157+
# Rule 3. app/ db/ srv/ custom-alt.cds if there is some custom-alt.cds file directly in the test_dir
158+
ROOT_FILES=$(find . -maxdepth 1 -type f -name '*.cds' -printf '%f ' 2>/dev/null || find . -maxdepth 1 -type f -name '*.cds' | sed 's|^\./||' | tr '\n' ' ')
159+
COMPILE_TARGETS="app db srv $ROOT_FILES"
160+
echo " Using CAP directories and root CDS files as compilation targets: app db srv $ROOT_FILES"
161+
fi
162+
fi
163+
164+
# Use npx with project-specific version to ensure compatibility
165+
cds_dk_package="@sap/cds-dk@$preferred_dk_version"
166+
echo " Running: npx --yes --package $cds_dk_package cds compile $COMPILE_TARGETS --locations --to json --dest model.cds.json"
167+
168+
# Disable exit-on-error for this compilation attempt
169+
set +e
170+
npx --yes --package "$cds_dk_package" cds compile \
171+
$COMPILE_TARGETS \
172+
--locations \
173+
--to json \
174+
--dest "model.cds.json" \
175+
--log-level warn
176+
COMPILE_EXIT_CODE=$?
177+
set -e
178+
179+
# Log compilation result
180+
if [ -f "model.cds.json" ]; then
181+
echo " ✓ Successfully generated model.cds.json in $(pwd)"
182+
# Add to list of generated files (convert to relative path)
183+
RELATIVE_PATH=$(get_relative_path "$(pwd)/model.cds.json" "$PROJECT_ROOT")
184+
GENERATED_FILES+=("$RELATIVE_PATH")
185+
else
186+
echo " ✗ Warning: model.cds.json was not generated in $(pwd) (exit code: $COMPILE_EXIT_CODE)"
187+
if [ -s "compilation.err" ]; then
188+
echo " Compilation errors:"
189+
cat "compilation.err" | sed 's/^/ /'
190+
fi
191+
fi
192+
193+
popd > /dev/null
194+
echo ""
195+
done
196+
197+
echo "=== COMPILATION SUMMARY ==="
198+
if [ ${#GENERATED_FILES[@]} -eq 0 ]; then
199+
echo "No model.cds.json files were generated."
200+
else
201+
echo "Generated ${#GENERATED_FILES[@]} model.cds.json file(s):"
202+
for file in "${GENERATED_FILES[@]}"; do
203+
echo " $file"
204+
done
205+
fi
206+
207+
echo ""
208+
echo "Test script completed."

0 commit comments

Comments
 (0)