Successfully Using SQLcl Projects If Your Production Branch Isn’t Called “main”

This short note demonstrates that the the production branch name is configurable in SQLcl projects. If you haven’t come across SQLcl projects yet, it’s Oracle’s opinionated framework for creating database applications. It is targeted towards enterprise-level applications that require structured release processes, making them especially well-suited for database CI/CD (Continuous Integration/Continuous Delivery). Since you can’t have CI/CD without your project being stored in version control, Git is at the heart of the workflow.

Recap: how to work with SQLcl projects

The general workflow in SQLcl projects for adding a new feature to an existing, SQLcl projects-managed application is as follows:

  • Create a short-lived branch off your production branch. For most of us the name of the production branch is MAIN or MASTER. The new branch is typically named after a ticket.
  • Log into a copy of your production database, perhaps running on your laptop based on Oracle Database Free. This copy doesn’t have to be a same-size copy for development purposes (we’re not talking about integration testing or load testing!), but it should be identical in terms of tables, indices, and code
  • Make your changes in your database
  • Run project export to generate the DDL statements (the command compares your branch against your production branch)
  • Commit these changes to the new branch
  • Run project stage to generate the “delta” scripts for deployment and necessary Liquibase changelogs
  • Merge your branch into your production branch

Please refer to the documentation for more information, there are optional steps involved that have been left out for clarity.

What if your target branch isn’t called MAIN?

That’s not a problem at all! Let me walk you through an example. Suppose you are introducing SQLcl projects to an existing application – why not use Dominic Giles’s Swingbench? It’s a great showcase of technology, and I have used it many times in the past.

I started by installing the Swingbench Order Entry schema (metadata only) in the SOE schema in Oracle Database Free’s FREEPDB1 pluggable database.

With that done, let’s start the SQLcl process; my main branch is named “trunk” by the way:

$ git status
On branch trunk
nothing to commit, working tree clean

Connecting to the SOE schema, I can run the initial project export after creating the new branch. I have a habit of creating a branch for every change I make – it’s easier to integrate into CI this way.

SOE@localhost/freepdb1 🚥>tables

TABLES
____________________
ADDRESSES
CARD_DETAILS
WAREHOUSES
ORDER_ITEMS
CUSTOMERS
ORDERS
INVENTORIES
PRODUCT_INFORMATION
LOGON
PRODUCT_DESCRIPTIONS
ORDERENTRY_METADATA

11 rows selected.
SOE@localhost/freepdb1 🚥>! git switch -c ticket-001
Switched to a new branch 'ticket-001'

SOE@localhost/freepdb1 🚥>project export
The current connection (DESCRIPTION=(LOAD_BALANCE=ON)(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=freepdb1))) SOE will be used for all operations
*** TABLES ***
*** SEQUENCES ***
*** INDEXES ***
*** PACKAGE_BODIES ***
*** PACKAGE_SPECS ***
*** VIEWS ***
*** REF_CONSTRAINTS ***
*** OBJECT_GRANTS ***
--------------------------------
GRANT 2
INDEX 18
PACKAGE_BODY 1
PACKAGE_SPEC 1
REF_CONSTRAINT 6
SEQUENCE 5
TABLE 11
VIEW 2
--------------------------------
Exported 46 objects
Elapsed 7 sec

Now that everything has been exported, it’s time for the first commit

SOE@localhost/freepdb1 🚥>! git commit -m 'feat: initial project export complete'
[ticket-001 0c801f3] feat: initial project export complete
53 files changed, 2356 insertions(+), 2 deletions(-)
create mode 100644 .dbtools/filters/project.filters

...

SOE@localhost/freepdb1 🚥>

Here’s where the difference lies compared to a “regular” project where your main branch is named MAIN or MASTER. The project stage command will fail:

SOE@localhost/freepdb1 🚥>project stage -verbose

Starting execution of stage command using the current branch

Stage is Comparing:
Old Branch refs/heads/main
New Branch refs/heads/ticket-001

ERROR: An error has occurred processing your request:
No branch reference was found. Make sure the branch exists and has at least one commit

As you can see from the output, the “old branch”—main—doesn’t exist. Let’s look at the project configuration:

SOE@localhost/freepdb1 🚥>project config -list -name git
+===========================================+
| SETTING NAME | VALUE |
+===========================================+
| git.protectedBranches | ["main","master"] |
+-------------------------------------------+
| git.defaultBranch | main |
+-------------------------------------------+

The project command expects main to be the default branch, yet it isn’t. It’s best to update these two fields to reflect that your production branch is named TRUNK, not MAIN:

SOE@localhost/freepdb1 🚥>project config set -name git.defaultBranch -value trunk
Process completed successfully
SOE@localhost/freepdb1 🚥>project config set -name git.protectedBranches -value ["main","master","trunk"]
Process completed successfully

As soon as that’s done, everything springs back into life:

SOE@localhost/freepdb1 🚥>project stage -verbose

Starting execution of stage command using the current branch

Stage is Comparing:
Old Branch refs/heads/trunk
New Branch refs/heads/ticket-001

Created dir: dist/releases
Created dir: dist/utils
Created dir: dist/releases/next
Created dir: dist/releases/next/changes
...
Updated change:dist/releases/next/release.changelog.xml
Updated change:dist/releases/next/release.changelog.xml

Completed executing stage command on branch: ticket-001

Stage processesing completed, please review and commit your changes to repository

Changes not staged for commit
modified: .dbtools/project.config.json

Untracked files:
dist
SOE@localhost/freepdb1 🚥>

That’s it! From there on it’s the same process as always.

Summary

This article explains how to configure SQLcl projects when your production branch uses a name other than the default “main” or “master”—for example, “trunk.” It walks through updating project configuration settings, demonstrates a sample workflow for introducing SQLcl projects to an existing application, and highlights how proper branch management supports CI/CD practices in database development environments. With these steps, teams can ensure a smooth integration of SQLcl projects regardless of their chosen production branch naming conventions.

Happy developing!