Version Control for IFS Customisations: Git Strategy and Workflows

Version Control for IFS Customisations: Git Strategy and Workflows

How to use Git for IFS custom code — managing Marble, PL/SQL, SSRS reports, and client files in monorepo or multi-repo strategies with effective branching and CI/CD.

IFSIFS CloudGitVersion ControlDevOpsCI/CDDevelopment

Introduction

Managing IFS customisations without version control is like flying blind. Whether you're building Marble components, crafting PL/SQL extensions, designing SSRS reports, or managing client-specific configurations, Git becomes your safety net—protecting against overwrites, enabling collaboration, and keeping a complete audit trail of every change.

But Git alone isn't the answer. The real challenge lies in structuring your repository strategy and implementing workflows that actually work for distributed IFS development teams.

This guide covers everything from monorepo vs. multi-repo decisions to branching strategies, CI/CD pipelines, and code review practices—all tailored for the unique demands of IFS customisations.


Part 1: Repository Strategy – Monorepo vs. Multi-Repo

Your repository structure shapes how teams collaborate, how changes flow through testing, and how quickly you can iterate. There's no one-size-fits-all answer, but understanding the trade-offs will guide your decision.

What Is a Monorepo?

A monorepo stores all customisation code—Marble components, PL/SQL modules, SSRS definitions, configuration scripts, and client files—in a single Git repository. Think of it as a unified codebase where every piece of customisation lives together.

Monorepo Benefits:

  • Unified Visibility: Developers see the entire customisation landscape in one place. Finding dependencies between Marble components and PL/SQL procedures becomes straightforward.
  • Simplified Dependency Management: Shared libraries (e.g., common Marble utilities) are versioned together. No version mismatches between components.
  • Atomic Cross-Component Refactoring: If a PL/SQL function changes its interface, you can update all calling Marble components in a single pull request, with a single set of tests.
  • Easier Onboarding: New team members clone one repo, run setup once, and have everything they need.
  • Unified CI/CD Pipeline: One build pipeline tests Marble, PL/SQL, SSRS, and configuration changes together, catching integration issues early.

Monorepo Challenges:

  • Repository Size: IFS monorepos can grow large, especially with historical commits and binary SSRS definitions. git status and git clone may slow down over time.
  • Blast Radius: A breaking change in core PL/SQL can block the entire team's development until fixed.
  • Slower Test Cycles: All tests (Marble, database, reports) run for every change, even if only one component was modified.
  • Access Control Complexity: Granting read-only access to specific components (e.g., client A's customisations) becomes difficult with a single repo.

What Is a Multi-Repo?

A multi-repo strategy uses separate repositories for distinct logical units: one for Marble components, one for PL/SQL modules, one for SSRS reports, and separate repos for client-specific customisations.

Multi-Repo Benefits:

  • Independent Versioning & Releases: Each repo can have its own version scheme and release cycle. Marble v2.1 can ship independently of PL/SQL updates.
  • Scalability: Developers clone only what they need, keeping local operations fast.
  • Team Autonomy: The Marble team owns their repo; the PL/SQL team owns theirs. Minimal coordination overhead.
  • Isolated Blast Radius: A bug in client A's customisations doesn't affect client B's repo.
  • Granular Access Control: Restrict access by repository, not by directory permissions.

Multi-Repo Challenges:

  • Dependency Hell: When Marble components depend on PL/SQL functions, managing version compatibility requires careful coordination and explicit dependency declarations.
  • Code Duplication: Common utilities may be duplicated across repos instead of shared.
  • Complex Integration Testing: Testing Marble + PL/SQL + SSRS together requires orchestrating multiple repos, branch coordination, and build steps.
  • Onboarding Friction: New developers must clone multiple repos, understand interconnections, and learn different build processes for each.

Decision Matrix: Monorepo vs. Multi-Repo for IFS

FactorMonorepoMulti-Repo
Team Size3–20 developers20+ developers across specialties
Shared CodeHigh (common libs, utilities)Low (independent components)
CouplingTight (interdependencies)Loose (independent services)
Release CycleSynchronized (monthly/quarterly)Independent (per-component)
Codebase Size<50 GBCan scale beyond 100+ GB
Access Control NeedLowHigh (different client tiers)
CI/CD ComplexitySimpler unified pipelineMultiple pipelines to orchestrate
Best ForIntegrated IFS implementationsLarge enterprises with multiple clients

Recommendation for IFS Teams

Start with a monorepo if:

  • You're a small to mid-sized team (under 20 developers).
  • Your customisations are tightly integrated (Marble calls PL/SQL, PL/SQL serves SSRS reports).
  • You want fast feedback and simplified CI/CD.
  • You have a single client or tightly aligned client requirements.

Use multi-repo if:

  • You're managing multiple independent clients with different release cycles.
  • You have specialised teams (one for Marble, one for database, one for reports).
  • You need strict access control or isolation between client customisations.
  • Your monorepo has become unwieldy (>50 GB, slow operations).

Part 2: Branching Strategies

With your repository structure decided, the next decision is how branches flow. A well-designed branching strategy prevents conflicts, enables parallel development, and keeps deployment risk low.

Git Flow (Release-Based)

Git Flow uses multiple long-lived branches to manage development and releases. It's ideal for IFS projects with scheduled release windows and formal testing phases.

Branch Types:

  • main: Production-ready code. Tagged with version numbers (v2.1.0, v2.2.0).
  • develop: Integration branch where features merge. Somewhat stable, used for UAT.
  • feature/[name]: Short-lived branches for individual features or bugs. Example: feature/marble-cost-calc, bugfix/ssrs-pagination.
  • release/[version]: Branches for preparing a release. Bug fixes only; no new features. Examples: release/2.2.0.
  • hotfix/[ticket]: Emergency fixes from main. Example: hotfix/PROJ-1234-critical-report-error.

Workflow:

  1. Developer creates feature/my-feature from develop.
  2. Work is committed, tested locally, and a pull request is opened for code review.
  3. Once approved and tests pass, merge into develop.
  4. When ready for a release, create release/2.2.0 from develop.
  5. QA tests; bug fixes go into release/2.2.0.
  6. Merge release/2.2.0 into main and tag with v2.2.0.
  7. Merge release/2.2.0 back into develop to keep it in sync.
  8. For urgent production issues, create hotfix/INC-123 from main, fix, merge into both main and develop.

Pros:

  • Clear separation between development and production.
  • Well-suited for formal release schedules (e.g., "release on the last Friday of each month").
  • Easy to maintain multiple versions in production if needed.

Cons:

  • More overhead; more branches to manage.
  • Can lead to long-lived feature branches that accumulate merge conflicts.
  • Slower time-to-production compared to continuous deployment.

Trunk-Based Development (Continuous Delivery)

Trunk-based development uses short-lived branches (1–3 days) flowing into a single main branch. It's modern, reduces merge conflicts, and suits teams practicing continuous deployment.

Branch Types:

  • main (or trunk): Always deployable. Directly merged to production or behind feature flags.
  • feature/[name]: Short-lived branches (max 2–3 days). Example: feature/marble-custom-field-type.

Workflow:

  1. Developer creates feature/my-feature from main.
  2. Work is committed daily; frequent, small pull requests (not monolithic).
  3. Code review happens quickly.
  4. Merge into main only after passing all tests and review.
  5. Main is automatically deployed to staging; manually to production once validated.
  6. No release branches; deployments happen continuously.

Pros:

  • Reduces merge conflicts (shorter-lived branches).
  • Faster feedback; quicker time-to-production.
  • Forces smaller, more reviewable changes.
  • Simpler mental model; one main branch to care about.

Cons:

  • Requires strong CI/CD and automated testing (if tests fail, main is broken).
  • Demands discipline—developers must keep branches short and tests passing.
  • Not ideal if you need to maintain multiple production versions simultaneously.

Recommendation for IFS

Use Git Flow if:

  • You have a formal release schedule (e.g., quarterly releases).
  • You maintain multiple production versions (supporting older IFS releases).
  • Your testing process requires a dedicated QA phase before release.

Use Trunk-Based if:

  • You're practicing continuous deployment or weekly releases.
  • Your team is mature and disciplined about testing and code review.
  • You want faster iteration and lower merge conflict overhead.

Part 3: Managing IFS-Specific Artifacts

Different IFS customisation types have unique version control needs.

Marble Models

“Marble” is commonly used for IFS Cloud model sources such as projections, clients and fragments. Entity and enumeration models are XML-backed in current Developer Studio tooling, while customer-layer server implementation is normally held in .plsql files. Store the complete customer solution source—not just the visible page model—in the layout expected by the target IFS component/build tooling.

Best Practices:

  • Store .projection, .client, .fragment, .entity, .enumeration, and related .plsql sources in Git, together with required manifests/build metadata. Review XML-backed model changes semantically as well as textually.
  • Exclude generated or local-only output: Don't commit generated clutter, local caches, or IDE workspace state unless your project explicitly requires it.
  • .gitignore for IFS development: Exclude temporary files, cache directories, and local IDE configurations.
# Local tooling/cache output
.metadata/
.settings/
node_modules/
dist/
  • Branching: Treat Marble model changes like any feature branch. Keep related projection and client changes together.
  • Testing: Validate Marble in the target IFS Developer Studio version, generate/deploy to a development environment, and test in IFS Cloud Web.

PL/SQL Procedures & Packages

IFS Cloud customer-layer database source normally lives in the component source tree as .plsql and generated/model artefacts. Standalone SQL may still be appropriate for an external customer-owned database or an authorised Apps 10 installation script, but it is not interchangeable with an IFS Cloud Lifecycle Experience delivery.

Best Practices:

  • Follow the generated logical-unit/component layout: keep customer-layer .plsql beside the model/source it extends; do not split generated extension methods into an arbitrary generic migration directory.
  • Use the IFS delivery mechanism: model persistent changes in IFS source and deliver the customer solution through the supported build/LEX process. Flyway or Liquibase can govern a separate integration database, not the managed IFS application schema.
  • Keep schema ownership out of source logic: call public/generated APIs without hard-coding IFSAPP. ${SCHEMA_PREFIX} is not native PL/SQL substitution syntax unless a separately governed installer expands it.

The directory is illustrative; use the registered component's actual source tree. A customer-layer file normally contains the generated header/sections and must be validated by Developer Studio, not pasted as an independent CREATE OR REPLACE script.

  • Branching: Database schema changes are high-risk. Use feature branches, but enforce code review and automated testing against a dev database before merging.

SSRS Reports

SSRS report definitions are XML files (.rdl). While they can be stored in Git, they have unique challenges.

Best Practices:

  • Export .rdl files from Report Server and commit them as text. Example: src/reports/FinancialSummary.rdl.
  • Expect messy diffs: SSRS rearranges XML elements without changing functionality. Diff-ability is poor, but history is still valuable for rollback.
  • Use CI/CD to validate: Automated tests should deploy reports to a test Report Server and verify rendering.
  • Branching: Keep report changes isolated. One report per feature branch.
  • .gitignore for SSRS:
# SSRS
*.rdl.bak
obj/          # compiled reports
bin/          # build output
  • Deploy separately: Consider deploying SSRS definitions via separate pipelines from application code. This reduces coupling.

Client-Specific Configurations

Client customisations (e.g., business rules, field mappings, workflow configurations) often differ. How you version them depends on your repo strategy.

For Monorepo:

  • Create a clients/ directory: clients/client-a/, clients/client-b/.
  • Each subdirectory contains client-specific PL/SQL, Marble, and config files.
  • Use .gitignore to prevent accidental commits of production secrets (API keys, credentials).
clients/
├── client-a/
│   ├── marble-components/
│   ├── procedures/
│   └── config.yaml
├── client-b/
│   ├── marble-components/
│   ├── procedures/
│   └── config.yaml
└── shared/
    ├── utilities/
    └── common-procedures/

For Multi-Repo:

  • Each client gets a dedicated repository. Example: ifs-client-a-customisations, ifs-client-b-customisations.
  • Shared utilities live in a separate ifs-shared-libraries repo, referenced as a Git submodule or dependency.

Environment-Specific Secrets:

  • Never commit production database credentials, API keys, or connection strings.
  • Use environment variables or a secrets manager (e.g., HashiCorp Vault, AWS Secrets Manager).
  • Store example configs in Git with placeholders: config.example.yaml.

Part 4: Effective Code Review & Collaboration

Version control is only as strong as your code review discipline.

Pull Request Workflow

  1. Branch Protection Rules: Enforce code review before merging.

    • Require at least one approval from a team lead.
    • Require all CI checks (tests, linting, security scans) to pass.
    • Require branches to be up-to-date with main before merging.
  2. PR Titles & Descriptions: Be specific.

    Title: feat: add marble cost-calculation component
    
    Description:
    - Implements cost calculation for multi-tier pricing
    - Adds PL/SQL procedure: CALC_TIERED_COST
    - Updates Marble to expose cost fields in grid
    - Resolves PROJ-1234
    
    Depends on: PR #456 (schema migration)
    
  3. Code Review Checklist:

    • Does the code meet IFS development standards?
    • Are database changes backward compatible?
    • Are SSRS datasets optimized?
    • Are secrets/credentials excluded from the commit?
    • Is there test coverage?
    • Are comments/docs clear for maintainers?
  4. Automate Repetitive Checks:

    • Linting (SQL formatting, consistent naming).
    • Security scans (detect hardcoded credentials).
    • Unit tests (PL/SQL testing via utPLSQL or similar).
    • Integration tests (Marble + PL/SQL interaction).

Commit Message Standards

Use conventional commits to make history searchable and auto-generate changelogs.

feat(marble): add custom cost-field to quotation component
fix(database): correct tiered pricing calculation logic
docs(readme): update setup instructions for Marble
refactor(plsql): consolidate cost-calc procedures
test: add unit tests for tiered pricing
ci: add SSRS validation to pipeline

Format: <type>(<scope>): <subject>

  • type: feat, fix, docs, refactor, test, ci, chore
  • scope: marble, database, ssrs, config, etc.
  • subject: concise description; lowercase; imperative mood

Part 5: CI/CD Integration

Automated testing and deployment are the backbone of safe, fast customisation delivery.

Typical IFS CI/CD Pipeline

┌─ Developer pushes feature branch
│
├─ Trigger GitHub Actions / GitLab CI / Jenkins
│
├─ LINT & FORMAT CHECK
│  └─ Validate SQL syntax, Marble models, SSRS defs
│
├─ BUILD
│  └─ Compile PL/SQL, generate/deploy Marble models, build reports
│
├─ UNIT TESTS
│  └─ Run utPLSQL for procedures; run app or integration tests where applicable
│
├─ INTEGRATION TESTS
│  └─ Install the candidate in an authorised, release-aligned IFS test environment
│
├─ SECURITY SCAN
│  └─ Check for hardcoded secrets, dependency vulnerabilities
│
├─ CODE REVIEW
│  └─ Human approval on GitHub/GitLab
│
└─ MERGE & DEPLOY
   └─ Auto-deploy to staging on merge to main
   └─ Manual gate for production deployment

Example GitHub Actions Workflow Shape

There is no public Oracle container that becomes an “ephemeral IFS Cloud” instance. An Oracle XE image lacks IFS schemas, generated APIs, identity, middleware and licensing context. CI should validate what it can locally, request/build the customer solution through the organisation's approved IFS lifecycle tooling, then deploy to a governed test environment.


Secrets Management

Never commit sensitive data. Use environment secrets:


Prefer protected environment secrets, short-lived/federated credentials, or an approved vault over broad repository secrets. IFS projection APIs use the OAuth/identity configuration supported by the target environment; a generic IFS_REST_API_KEY is not a standard authentication contract.


Part 6: Key Takeaways & Best Practices

Checklist for IFS Git Mastery

Repository Structure

  • Decided monorepo vs. multi-repo based on team size and coupling.
  • Preserved the component/source layout required by IFS tooling, with a documented home for external services, reports and client-specific variants.

Branching Strategy

  • Chose Git Flow (scheduled releases) or Trunk-Based (continuous deployment).
  • Documented naming conventions: feature/, bugfix/, hotfix/, release/.

Code Quality

  • Enforce branch protection rules (code review + passing tests).
  • Automated linting, syntax checking, and security scans in CI.
  • Conventional commit messages for searchable history.

Testing

  • Unit tests for PL/SQL procedures (utPLSQL).
  • Integration tests validating Marble ↔ PL/SQL ↔ SSRS interactions.
  • Release-aligned IFS test environment and controlled candidate-install process available for integration testing.

Secrets & Security

  • No credentials in Git; use environment variables or secrets manager.
  • .gitignore excludes sensitive files, build artifacts, and local configs.
  • Security scanning (SAST, dependency checks) in CI/CD.

Collaboration

  • Detailed PR descriptions linking to tickets.
  • Code review checklist for maintainability and standards.
  • Runbooks for common operations (schema migration, Marble deployment, report publishing).

Common Pitfalls to Avoid

Committing Binary SSRS Artifacts: .rdl files change XML structure unpredictably. Version source files; regenerate at build time.

Monolithic Feature Branches: 200+ line changes are hard to review. Keep PRs under 500 lines; merge frequently.

Skipping Integration Tests: Marble + database + reports work in isolation but fail together. Test the full stack.

Ignoring .gitignore: Accidentally commit config-prod.sql with hardcoded passwords. Use templates; store secrets outside Git.

Slow Code Review: Week-long reviews block teams. Aim for 24-hour SLAs.

Tools & Extensions

  • Git Flow Tools: git-flow CLI extension simplifies branch management.
  • CI/CD: GitHub Actions, GitLab CI, Jenkins, Azure Pipelines.
  • Testing: utPLSQL (PL/SQL), Playwright or Selenium for browser flows, and project-specific API checks.
  • Secrets: HashiCorp Vault, AWS Secrets Manager, Azure Key Vault.
  • Linting: SQLFluff (SQL), ESLint (JavaScript), IFS Developer Studio validation for Marble, and XML validators where the artefact really is XML such as SSRS .rdl.

Conclusion

Version control for IFS customisations isn't just about preserving code history—it's about enabling safe, parallel development across distributed teams. Whether you choose a monorepo or multi-repo, Git Flow or Trunk-Based, the fundamentals remain: clear branching strategies, automated testing, peer review, and secure secrets management.

Start small. Pick a strategy that fits your team's size and release cycle. Iterate as you scale. And always remember: your Git history is a living document of your IFS customisations journey.

Additional Resources

Need a Git workflow that fits your IFS delivery model?

Syrett Consultancy can help you shape branching, repository structure, and release controls for IFS customisations across teams and environments.