Oracle APEX 23.2 introduced a new feature – Working Copies. It makes working on something by several developers simultaneously much easier to manage. How does it function, and what are its limitations?
Working Copies – introduced in APEX 23.2 – is a great feature. Sure, the ability to export the APEX application into YAML format (this part is doable), merge it into the GIT repository, and import a final version of the APEX app (still in YAML) into my database would be even better. But that’s the future (I don’t know how close), and Working Copies are here now. Let’s take a closer look at how it works in practice.
According to Oracle’s documentation, the feature allows you to create a copy of an application, make changes in that copy, and then merge those changes back into the Main Application. Similarly, you can merge changes from the Main Application into the Working Copy. During export, you can view a comparison (or diff) of the Working Copy and the Main Application and then select which changes to merge.
Well, here’s how I benefited from this feature:
- I don’t need a separate APEX development (DEV) environment for each developer (sure, some will ask: “What about the database?” but that’s a different topic).
- I always forget to lock pages I work on (or unlock them once finished) so I don’t have to remember about it anymore.
- I can review the developer’s changes in their working copies and decide what should be merged into the Main Application.
Here’s my specific use case:
- I’m using my workspace at apex.oracle.com.
- My Main Application (MA) is Sample Reporting MAIN APP 15014
- I will create two working copies for DEVELOPER_1 and DEVELOPER_2.
In this section, I’ll show you how the Working Copies feature works and how to use it in your projects. It’s not overly complicated.
Step 1 – Create a Working Copy
Go to the main page of the App Builder (as a DEVELOPER_1).
Two icons indicate you are in the main application right now.
Pick Create Working Copy.
Choose a name and click Create Working Copy.
Repeat these steps as DEVELOPER_2.
There is also an option to create a copy or switch to existing copies directly from the new context menu:
I also have an enhanced view showing the number of working copies (report or icons view):
The Working copies column was there by default, and the Working Copy Info was chosen by me from Actions -> Columns.
I had hoped that this nice GIT branch icon would grow with the number of copies, but it always shows two branches.
Step 2 – Choose a Working Copy to work on
To pick one of the created copies, go to the main page of the App Builder and select one from the right side.
What is this feature missing? An option to prevent other developers from using a working copy I created – make my copy exclusive to me.
No matter who I am logged in as (DEVELOPER_1 or DEVELOPER_2), I can see (and work on) all created working copies.
The working copy name is shown on the right of the main app name.
My application copy (created as DEVELOPER_1) received an ID 70529, and for DEVELOPER_2, the ID is 61613.
Also, the branch icon colour changed to brown (grey for the Main app). That’s good because it will be hard to change something in the main app by mistake.
What else is there? A new menu dedicated to Working Copies, for one. Some options are also repeated on the right side of the page for easier access.
Let’s look at APEX App Builder for a specific page I want to edit. There is the same context menu as on the main App Builder page, with a branch icon indicating that we are in Working Copy mode.
Now, let’s look at a different scenario – two developers making changes in two Working Copies.
Changes made by DEVELOPER_1 in a working copy “Sample Reporting DEVELOPER_1”
- A new column was added to a query in Classic Report on page 3.
- Changed the Interactive Grid title on page 17.
- I also changed the Automatic Time Zone to YES (unfortunately, merging Application Attributes is not supported – more about this later).
- I created a new page 16 with an empty Static Content region.
Now, DEVELOPER_1 is going for a coffee break (changes are not merged to the Main Application yet), and DEVELOPER_2 will be making changes in his own copy.
Changes made by DEVELOPER_2 in a working copy “Sample Reporting DEVELOPER_2”
- A new page with an Interactive Report was added.
Notice the page number assigned automatically – it’s also 16. The exact number was assigned to the new page created previously by DEVELOPER_1 ( but DEVELOPER_2 doesn’t know it yet).
- DEVELOPER_2 also created a new list of values.
- And new column was added to the report on page 3 (DEVELOPER_1 modified the same query in his working copy but DEVELOPER_2 doesn’t know about it)
Now, let’s compare changes made in Working Copies with the Main Application.
Working Copy “Sample Reporting DEVELOPER_1” changes vs. Main App
After finishing work, DEVELOPER_1 can review and merge his changes into the Main App.
What’s interesting is that DEVELOPER_1 is also allowed to use a Working Copy created by DEVELOPER_2 and do whatever he wants with that copy.
But first, we should compare changes made in the Working Copy with the Main App (there are two places you can do that in).
Quick shortcut/tip – you can skip comparing changes and go directly to Merge into Main and compare your changes there.
What happens next:
It seems like APEX is exporting the Main Application somewhere to YAML format.
The same thing is happening with the Working Copy.
It looks nice, but why can’t I sort by the Status column?
I also got a warning saying that some of my changes can’t be merged into the Main App (changes that aren’t supported yet). So, will everything be merged or not? Exact information would be nice.
DEVELOPER_1’s expected changes are:
- Changed the Classic Report Query on page 3, which looks good in the View Differences window.
- Changed the IG title on page 17 – it also looks good.
- Changed the Automatic Time Zone to YES in Globalization Attributes – oops! There’s no such change listed anywhere. It’s an Application Properties component that is not supported, but why can’t it be listed with the status “NOT SUPPORTED TO MERGE”?
- Added new page 16, with an empty Static Content region – all the changes seem to be there.
Working Copy “Sample Reporting DEVELOPER_2” changes vs. Main App
Now, let’s review the changes made by DEVELOPER_2. They are as follows:
- Added new page 16 with an Interactive Report.
- One LOV in Shared Components was created.
- Changed the Classic Report Query on page 3.
All changes seem to be there.
But I still have this warning that I might have some modifications that cannot be merged, although I believe all the above changes are supported.
Merging changes from Working Copies to the Main Application
Now, let’s examine merging the changes made in Working Copies with the Main Application.
Merge from Working Copy “Sample Reporting DEVELOPER_1” into the Main App
DEVELOPER_1 is ready to merge his changes into the Main App.
Here comes the export again.
I have a list of my changes, and I can choose what I want to merge. I can also still see my Differences View by clicking the Diff icon (it does the same thing as the Compare changes option).
However, I still see a warning saying that some of my modifications might not be changed. Which ones and why are they listed here? Unfortunately, these details are unclear– there’s clearly room for improvement here.
I think this is about my change in Globalization Attributes, which is not even listed here.
I click Next and see this:
There are two extra features:
- Backup target app first
- Delete the Working Copy after the merge
Deleting a working copy can always wait, but it’s nice that backing up the Main App is a default option. We always do backups and remember about it, don’t we? 🙂
I leave the default values and click Confirm Merge.
It took about 5 seconds and automatically moved me to my Main App view with a fantastic message: “Your changes have been successfully merged!”.
Weren’t there supposed to be some changes that couldn’t be merged due to unsupported types? Were they all merged?
It also looks like a backup was created.
Let’s have a look at recently edited components in my Main App:
Looks good. All were merged, and my Main App is now improved with new features/changes from the working copy of DEVELOPER_1.
Merge from Working Copy “Sample Reporting DEVELOPER_2” into the Main App
Now, DEVELOPER_2 is ready to merge his changes into the Main App.
DEVELOPER_2 can easily review changes and differences, deciding what should be merged into the Main App.
In the example below, a developer can see that page 16 is listed as Changed instead of Added because DEVELOPER_1 merged his new page with the same number into the Main App.
Components with the Missing status don’t exist in DEVELOPER_2‘s Working Copy but exist in the Main App.
This screen will allow you to resolve conflicts and choose what to merge or exclude easily:
In this example, I will choose everything I can.
The merge was a small crash – but that was intended.
Let’s take a look into the Main App now. I had some conflicts, and because I decided to merge everything from the DEVELOPER_2 Working Copy, the final result looks like below.
Page 3 with a Classic Report:
Developer_1_New_column was lost, and it would still be there if I refreshed my Working Copy before merging. However, this behaviour was as expected.
Regarding Page 16 (created by both developers):
A version of this page (created by DEVELOPER_1, with only static content inside) was removed and replaced with the version created by DEVELOPER_2 (with Interactive Report).
You are probably wondering how it is possible that the Main App shows DEVELOPER_1_NEW_PAGE while DEVELOPER_2‘s changes overwrote it.
This is because breadcrumbs are separate components and were created by both developers during page creation.
Since both breadcrumbs have the attribute Page -> 16, then APEX renders the first one matching, which is DEVELOPER_1_NEW_PAGE.
A helpful tip: Always refresh Working Copies with the Main Application
It could be a good practice for developers to always refresh the Working Copy with the Main App before merging changes to the Main App.
It would allow developers to get all changes made in the Main App since creating their Working Copy. In that case, DEVELOPER_2 could pull all the changes made by DEVELOPER_1 – from the moment DEVELOPER_2 created his Working Copy – into the Main Application.
It should minimize conflicts and reduce unnecessary work that may have already been implemented into the Main Application. It should also help avoid merge issues that occur while merging the DEVELOPER_2’s working copy into the Main App.
Refreshing looks the same way as merging into the Main App. The difference is that you merge changes from the Main App into your Working Copy.
Here’s some information from Oracle that shows up when you click on the More information button while comparing changes/merging Working Copies.
Full documentation is here.
Overall, I think it’s an outstanding feature that works very well – keeping in mind that it’s only in pre-production release. I hope it keeps getting better.
What I particularly like:
- The Working Copy feature is like GIT inside APEX. As someone who values versioning and controlling deployments, I really appreciate this feature.
- Respect for the APEX Team for assuming people don’t take backups by default. They’re absolutely right! That’s why this checkbox marked by default during merging is – almost – a life-changer.
- And If I uncheck this checkbox, this happens:
- A way to lock Working Copies and make them visible/editable only for selected users/creators of it.
- Ordering/filtering by Status at the list of changes to merge/compare.
- A feature that will prevent some developers from working on the Main App and allow them to work/edit only their working copies. It would allow DevOps guys (more privileged) to review changes and decide what should be merged into the Main App.
- Instead of – or in addition to – the message below, I’d prefer to have an exact list of changes I’ve made that can’t be merged into my Main Application. Now, I need to guess and search in documentation.
- It would be helpful to have an indicator in my working copy telling me: “Hey, someone changed something in the main application. How about refreshing your copy?”
And that sums up this article. I’m interested in your thoughts and perspective. Have you tried the feature already? Let me know at email@example.com. And while you wait for my reply, you can also check out my other articles on this blog:
- What is Liquibase and how to start using it? Automate your database scripts deployment with this Liquibase tutorial
- Boost the management of your Oracle Database version control changes with Liquibase
- Oracle data masking: hide information from users with an easy-to-use VPD
- Use Liquibase to track DB changes without direct access – A quick guide
- Use SQLcl Liquibase to move all database objects from DEV to the UAT environment