Skip to content

test sf cli

test sf cli #4

name: SF CLI Integration Test
on:
pull_request:
jobs:
sf-cli-integration:
runs-on: ubuntu-latest
env:
SF_AUTOUPDATE_DISABLE: true
NO_COLOR: '1'
steps:
# ── Setup ─────────────────────────────────────────────────────────────────
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install Poetry and Python SDK
run: |
python -m pip install --upgrade pip
pip install poetry
make develop
- name: Add Poetry venv to PATH
run: echo "$(poetry env info --path)/bin" >> $GITHUB_PATH
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install Salesforce CLI
run: npm install -g @salesforce/cli
- name: Install data-code-extension plugin
run: sf plugins install @salesforce/plugin-data-code-extension --force
- name: Set up Java 17 (required for PySpark during run)
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
# ── Mock Salesforce server + fake org auth ────────────────────────────────
- name: Start mock Salesforce server
run: python scripts/mock_sf_server.py &
env:
MOCK_SF_PORT: '8888'
- name: Register fake org 'dev1' with SF CLI
run: |
sleep 1
echo "00D000000000001AAA!fakeAccessTokenForCITesting" | \
sf org login access-token \
--instance-url http://localhost:8888 \
--alias dev1 \
--no-prompt
# ── Script: init ──────────────────────────────────────────────────────────
- name: '[script] init — sf data-code-extension script init --package-dir testScript'
run: |
sf data-code-extension script init --package-dir testScript || {
echo "::error::sf data-code-extension script init FAILED. Verify --package-dir is still a recognised flag and that the command exits 0 on success."
exit 1
}
- name: '[script] verify init — expected files exist'
run: |
test -f testScript/payload/entrypoint.py || {
echo "::error::testScript/payload/entrypoint.py not found after init. The init command may not have copied the script template."
exit 1
}
test -f testScript/.datacustomcode_proj/sdk_config.json || {
echo "::error::testScript/.datacustomcode_proj/sdk_config.json not found after init. The SDK config marker was not written."
exit 1
}
# ── Script: scan ──────────────────────────────────────────────────────────
- name: '[script] scan — sf data-code-extension script scan --entrypoint testScript/payload/entrypoint.py'
run: |
sf data-code-extension script scan --entrypoint testScript/payload/entrypoint.py || {
echo "::error::sf data-code-extension script scan FAILED. Verify --entrypoint is still a recognised flag and the command exits 0."
exit 1
}
- name: '[script] verify scan — config.json contains permissions'
run: |
python - <<'EOF'
import json, sys
path = "testScript/payload/config.json"
try:
with open(path) as f:
data = json.load(f)
except Exception as e:
print(f"::error::Could not read {path}: {e}")
sys.exit(1)
if "permissions" not in data:
print(f"::error::{path} is missing 'permissions' key after scan. Got: {json.dumps(data)}")
sys.exit(1)
print("config.json OK:", json.dumps(data, indent=2))
EOF
# ── Script: zip ───────────────────────────────────────────────────────────
- name: '[script] prepare for zip — clear requirements.txt to skip native-dep Docker build'
run: echo "" > testScript/payload/requirements.txt
- name: '[script] zip — sf data-code-extension script zip --package-dir testScript'
run: |
sf data-code-extension script zip --package-dir testScript || {
echo "::error::sf data-code-extension script zip FAILED. Verify --package-dir is still recognised and the command exits 0."
exit 1
}
- name: '[script] verify zip — deployment.zip exists'
run: |
test -f deployment.zip || {
echo "::error::deployment.zip not found after sf data-code-extension script zip. The zip command may have written to a different path or failed silently."
exit 1
}
# ── Script: run ───────────────────────────────────────────────────────────
- name: '[script] run — sf data-code-extension script run --entrypoint testScript/payload/entrypoint.py -o dev1'
run: |
sf data-code-extension script run \
--entrypoint testScript/payload/entrypoint.py \
-o dev1 || {
echo "::error::sf data-code-extension script run FAILED. Check mock server output above for which endpoint failed. The --entrypoint flag or SF CLI org auth contract may have changed."
exit 1
}
# ── Function: init ────────────────────────────────────────────────────────
- name: '[function] init — sf data-code-extension function init --package-dir testFunction'
run: |
sf data-code-extension function init --package-dir testFunction || {
echo "::error::sf data-code-extension function init FAILED. Verify --package-dir is still recognised and the function template copies correctly."
exit 1
}
- name: '[function] verify init — expected files exist'
run: |
test -f testFunction/payload/entrypoint.py || {
echo "::error::testFunction/payload/entrypoint.py not found after function init."
exit 1
}
test -f testFunction/.datacustomcode_proj/sdk_config.json || {
echo "::error::testFunction/.datacustomcode_proj/sdk_config.json not found after function init."
exit 1
}
# ── Function: scan ────────────────────────────────────────────────────────
- name: '[function] scan — sf data-code-extension function scan --entrypoint testFunction/payload/entrypoint.py'
run: |
sf data-code-extension function scan --entrypoint testFunction/payload/entrypoint.py || {
echo "::error::sf data-code-extension function scan FAILED."
exit 1
}
- name: '[function] verify scan — config.json contains entryPoint'
run: |
python - <<'EOF'
import json, sys
path = "testFunction/payload/config.json"
try:
with open(path) as f:
data = json.load(f)
except Exception as e:
print(f"::error::Could not read {path}: {e}")
sys.exit(1)
if "entryPoint" not in data:
print(f"::error::{path} is missing 'entryPoint' key after scan. Got: {json.dumps(data)}")
sys.exit(1)
print("config.json OK:", json.dumps(data, indent=2))
EOF
# ── Function: zip ─────────────────────────────────────────────────────────
- name: '[function] prepare for zip — clear requirements.txt to skip native-dep Docker build'
run: echo "" > testFunction/payload/requirements.txt
- name: '[function] clean up previous deployment.zip before function zip'
run: rm -f deployment.zip
- name: '[function] zip — sf data-code-extension function zip --package-dir testFunction'
run: |
sf data-code-extension function zip --package-dir testFunction || {
echo "::error::sf data-code-extension function zip FAILED."
exit 1
}
- name: '[function] verify zip — deployment.zip exists'
run: |
test -f deployment.zip || {
echo "::error::deployment.zip not found after sf data-code-extension function zip."
exit 1
}
# ── Function: run ─────────────────────────────────────────────────────────
- name: '[function] run — sf data-code-extension function run --entrypoint testFunction/payload/entrypoint.py -o dev1'
run: |
sf data-code-extension function run \
--entrypoint testFunction/payload/entrypoint.py \
-o dev1 || {
echo "::error::sf data-code-extension function run FAILED. Check mock server output above; the --entrypoint flag or SF CLI org auth contract may have changed."
exit 1
}