Skip to main content

SDF + Git Practice Guide

A hands-on practice guide for team collaboration using SDF and Git in VS Code. This guide walks through real-world scenarios with two developers working together.

Practice Team

This guide uses two example developers:

  • Developer A (ryandiocean)
  • Developer B (luckyocean)

Replace these with your actual team members when practicing.


Prerequisites

Before starting these exercises, ensure you have completed:


Git Flow Overview

This diagram shows how ryandiocean and luckyocean collaborate on the same codebase:

main ─────●─────────────────────────────────────●───────●─── (Production)
│ │ ↑
│ hotfix/NS-999│
│ └───────┘


develop ──●────●────●────●────●────●────●────●────●─────── (Integration)
│ ↑ │ ↑ │ ↑
│ │ │ │ │ │
ryandiocean luckyocean │
feature/ feature/ │
NS-123 NS-456 │
│ │ │
└─────────┘ │
↓ │
Both merge bugfix branches
to develop (NS-789, NS-790)
may conflict!

Branch Timeline Example

Two Developer Workflow

Stepryandioceanluckyocean
1git checkout -b feature/NS-123git checkout -b feature/NS-456
2Works on beforeSubmitWorks on afterSubmit
3Commits and pushesCommits and pushes
4Merges to develop first ✅Pulls develop, then merges ✅
5Both features in developNo conflict (different functions)

Practice Project Structure

For these exercises, we'll use a sample SDF project:

suitescript-demo/
├── manifest.xml # SDF project manifest
├── deploy.xml # Deployment configuration
├── suitecloud.config.js # SuiteCloud config
├── package.json # NPM dependencies
├── .gitignore
└── src/
├── FileCabinet/
│ └── SuiteScripts/
│ └── user_event_customer.js
└── Objects/
└── customscript_ue_customer_validation.xml

Scenario 1: Feature Development Without Conflict

Goal: Two developers work on different parts of the same file without creating conflicts.

Flow

ryandiocean                              luckyocean
│ │
├─ 1. checkout develop │
├─ 2. create feature/NS-123 │
├─ 3. edit beforeSubmit │
├─ 4. commit & push │
├─ 5. merge to develop ✅ │
│ │
│ 6. checkout develop
│ 7. pull (gets A's code)
│ 8. create feature/NS-456
│ 9. edit afterSubmit
│ 10. commit & push
│ 11. merge to develop ✅

Result: No conflict because they edited different functions (beforeSubmit vs afterSubmit).

Developer A: Add Email Validation (NS-123)

# Start from develop
git checkout develop
git pull origin develop
git checkout -b feature/NS-123-email-validation

Edit src/FileCabinet/SuiteScripts/user_event_customer.js - add in beforeSubmit:

// Email validation (NS-123 - Developer A)
var email = customer.getValue({ fieldId: 'email' });
if (email && email.indexOf('@') === -1) {
throw Error('Invalid email format');
}

Validate and commit:

# Validate in VS Code
# Ctrl+Shift+P → SuiteCloud: Validate Project

git add .
git commit -m "[NS-123] Add email validation in beforeSubmit"
git push origin feature/NS-123-email-validation

Test in Sandbox:

MethodWhen to UseHow
Upload FileQuick test, single file onlyRight-click file → Upload File to Account
Deploy ProjectNew scripts, XML changes, multiple filesCtrl+Shift+PSuiteCloud: Deploy Project
Upload File for Quick Testing

If you only changed one script file and want to test quickly without deploying the entire project:

  1. Right-click the .js file in VS Code Explorer
  2. Select "Upload File to Account"
  3. Choose your Sandbox account
  4. File uploads instantly to File Cabinet

This is faster than full project deploy but only works for existing scripts (the script deployment record must already exist in NetSuite).


Developer B: Add Phone Logging (NS-456)

# Start from develop (in parallel)
git checkout develop
git pull origin develop
git checkout -b feature/NS-456-phone-logging

Edit src/FileCabinet/SuiteScripts/user_event_customer.js - add in afterSubmit:

// Phone logging (NS-456 - Developer B)
var phone = customer.getValue({ fieldId: 'phone' });
log.audit('Customer Phone', 'Phone: ' + phone);

Validate and commit:

git add .
git commit -m "[NS-456] Add phone logging in afterSubmit"
git push origin feature/NS-456-phone-logging

Merging Both Features (No Conflict)

Since developers modified different functions (beforeSubmit vs afterSubmit), Git can merge automatically.

Developer A merges first:

git checkout develop
git pull origin develop
git merge feature/NS-123-email-validation
git push origin develop

Developer B merges after:

git checkout develop
git pull origin develop
git merge feature/NS-456-phone-logging
git push origin develop

Result: Both features are now in develop without conflicts.


Scenario 2: Creating and Resolving Merge Conflicts

Goal: Intentionally create a conflict to practice resolution.

Flow

ryandiocean                              luckyocean
│ │
├─ 1. create bugfix/NS-789 ├─ 2. create bugfix/NS-790
├─ 3. edit SAME line ├─ 4. edit SAME line
├─ 5. commit & push (to own branch ✅) ├─ 6. commit & push (to own branch ✅)
├─ 7. checkout develop │
├─ 8. pull develop │
├─ 9. merge NS-789 to develop ✅ │
├─ 10. push develop ✅ │
│ │
│ 11. checkout develop
│ 12. pull develop (gets A's changes)
│ 13. merge NS-790 → CONFLICT!
│ 14. open VS Code, see markers
│ 15. combine both changes
│ 16. validate with SuiteCloud
│ 17. git add → git commit
│ 18. push develop ✅
Why No Push Rejection at Step 6?

Each developer pushes to their own branch (bugfix/NS-789 and bugfix/NS-790), not to develop. Push rejection only occurs when pushing to a branch that has commits you don't have locally. The conflict happens during merge (step 13), not during push.

Developer A: Change Log Level (NS-789)

git checkout develop
git pull origin develop
git checkout -b bugfix/NS-789-log-level

Edit afterSubmit - CHANGE log.audit to log.debug:

log.debug('After Submit', 'Customer saved with ID: ' + customerId);
git add .
git commit -m "[NS-789] Change log level to debug"
git push origin bugfix/NS-789-log-level

Developer B: Add Timestamp (NS-790)

git checkout develop
git pull origin develop
git checkout -b bugfix/NS-790-timestamp

Edit the same line in afterSubmit:

log.audit('After Submit', 'Customer saved with ID: ' + customerId + ' at ' + new Date());
git add .
git commit -m "[NS-790] Add timestamp to log"
git push origin bugfix/NS-790-timestamp

The Conflict Occurs

Developer A merges first (success):

git checkout develop
git pull origin develop
git merge bugfix/NS-789-log-level
git push origin develop

Developer B tries to merge (CONFLICT!):

git checkout develop
git pull origin develop
git merge bugfix/NS-790-timestamp
# CONFLICT: Merge conflict in user_event_customer.js

Resolving the Conflict in VS Code

VS Code highlights the conflict:

<<<<<<< HEAD
log.debug('After Submit', 'Customer saved with ID: ' + customerId);
=======
log.audit('After Submit', 'Customer saved with ID: ' + customerId + ' at ' + new Date());
>>>>>>> bugfix/NS-790-timestamp

VS Code buttons above the conflict:

ButtonAction
Accept Current ChangeKeep HEAD version (debug)
Accept Incoming ChangeKeep incoming version (audit + timestamp)
Accept Both ChangesInclude both lines
Compare ChangesSide-by-side view

Best resolution - combine both changes:

  1. Click Accept Current Change
  2. Manually add the timestamp:
log.debug('After Submit', 'Customer saved with ID: ' + customerId + ' at ' + new Date());

Validate and complete the merge:

# Validate
Ctrl+Shift+P → SuiteCloud: Validate Project

git add .
git commit -m "Merge bugfix/NS-790: Resolved conflict - debug with timestamp"
git push origin develop

Scenario 3: Production Hotfix

Goal: Fix a critical production issue using the hotfix workflow.

Flow

1. Critical bug in Production!


2. git checkout main (branch from MAIN, not develop!)


3. git checkout -b hotfix/NS-999


4. Fix the bug in VS Code


5. Validate with SuiteCloud


6. Deploy to Production


7. Merge hotfix to main → push


8. Sync fix to develop ✅

Developer A: Critical Null Check (NS-999)

# Branch from MAIN (not develop!)
git checkout main
git pull origin main
git checkout -b hotfix/NS-999-null-check

Edit afterSubmit - add null check at the beginning:

function afterSubmit(context) {
// Hotfix NS-999 - null check
if (!context.newRecord) {
log.error('After Submit', 'No record found');
return;
}

var customer = context.newRecord;
// ... rest of code
}

Validate:

Ctrl+Shift+P → SuiteCloud: Validate Project

Commit and push:

git add .
git commit -m "[NS-999] HOTFIX: Add null check for context.newRecord"
git push origin hotfix/NS-999-null-check

Deploy to Production:

Ctrl+Shift+P → SuiteCloud: Deploy Project → Select Production

Merge to main AND develop:

# Merge to main
git checkout main
git merge hotfix/NS-999-null-check
git push origin main

# Also sync to develop
git checkout develop
git pull origin develop
git merge main
git push origin develop

Scenario 4: Syncing Changes Made in NetSuite UI

Goal: Import and version control changes made directly in NetSuite's web interface.

Flow

1. Someone edited script in NetSuite UI


2. Changes are NOT in Git!


3. Create sync branch from develop


4. Import Files (Ctrl+Shift+P → SuiteCloud: Import Files)


5. Import Objects (Ctrl+Shift+P → SuiteCloud: Import Objects)


6. Review changes in VS Code


7. Commit → Push → Merge to develop ✅

When to Use This

  • Someone edited a script directly in NetSuite
  • Custom record was modified via UI
  • Workflow was updated in NetSuite
  • Any change made outside of SDF deployment

Step-by-Step Process

# Create sync branch
git checkout develop
git pull origin develop
git checkout -b sync/NS-888-import-ui-changes

Import Files from NetSuite:

  1. Press Ctrl+Shift+P
  2. Type: SuiteCloud: Import Files
  3. Select your account
  4. Navigate to /SuiteScripts/
  5. Select the modified file(s)
  6. Click Import

Import Objects from NetSuite:

  1. Press Ctrl+Shift+P
  2. Type: SuiteCloud: Import Objects
  3. Select your account
  4. Choose object type (e.g., usereventscript)
  5. Select the specific object(s)
  6. Click Import

Commit and merge:

git add .
git commit -m "[NS-888] Sync changes from NetSuite UI

- Imported updated user_event_customer.js
- Imported customscript_ue_customer_validation.xml"

git push origin sync/NS-888-import-ui-changes

# Merge to develop
git checkout develop
git merge sync/NS-888-import-ui-changes
git push origin develop
Best Practice

Discourage direct NetSuite UI edits. Always prefer SDF deployment for version control. Use sync branches only when UI changes were unavoidable.


VS Code SuiteCloud Quick Reference

Command Palette (Ctrl+Shift+P)

ActionCommand
Set up accountSuiteCloud: Set Up Account
Deploy entire projectSuiteCloud: Deploy Project
Validate projectSuiteCloud: Validate Project
Import files from NetSuiteSuiteCloud: Import Files
Import objects from NetSuiteSuiteCloud: Import Objects
List objects in accountSuiteCloud: List Objects
Add dependency referencesSuiteCloud: Add Dependency References

Right-Click Context Menu

Right-click on a file in VS Code Explorer:

OptionDescription
Deploy to AccountDeploy single file to NetSuite
Compare with AccountCompare local vs NetSuite version
Upload File to AccountUpload without full project deploy

Keyboard Shortcuts

ActionShortcut
Command PaletteCtrl+Shift+P
Open TerminalCtrl+`
Source Control PanelCtrl+Shift+G
File ExplorerCtrl+Shift+E
Search in FilesCtrl+Shift+F
Save FileCtrl+S
Save All FilesCtrl+K S

Development Workflow Summary


Release to Production Workflow

# Merge develop to main
git checkout main
git pull origin main
git merge develop
git push origin main

# Deploy to production
Ctrl+Shift+P → SuiteCloud: Deploy Project → Production

# Tag the release
git tag -a v1.0.0 -m "Release version 1.0.0"
git push origin v1.0.0

Branch Naming Convention

TypeFormatExample
Featurefeature/NS-XXX-descriptionfeature/NS-123-email-validation
Bugfixbugfix/NS-XXX-descriptionbugfix/NS-456-fix-null-error
Hotfixhotfix/NS-XXX-descriptionhotfix/NS-999-critical-fix
Syncsync/NS-XXX-descriptionsync/NS-888-import-changes

Git Flow Diagram

main ─────●─────────────────────────●───────●─── (Production)
│ │ ↑
│ hotfix/NS-999│
│ └───────┘


develop ──●────●────●────●────●────●────●─────── (Integration)
│ ↑ │ ↑
│ │ │ │
feature/NS-123 bugfix/NS-790
└────┘ └────┘

Practice Exercises

Exercise 1: No-Conflict Merge

  1. Developer A creates feature/test-a with changes to beforeSubmit
  2. Developer B creates feature/test-b with changes to afterSubmit
  3. Both merge to develop without conflicts

Exercise 2: Conflict Resolution

  1. Developer A creates bugfix/test-a modifying line 50
  2. Developer B creates bugfix/test-b modifying the same line 50
  3. Practice resolving the conflict using VS Code merge editor

Exercise 3: Hotfix Flow

  1. Create a hotfix branch from main
  2. Fix an issue and deploy to production
  3. Sync the hotfix back to develop

Exercise 4: Import from NetSuite

  1. Make a small change to a script in NetSuite UI
  2. Create a sync branch
  3. Import the changes using SuiteCloud commands
  4. Commit and merge to develop