Skip to main content

Working copies in 26.2: test one page, never overwrite the app

Y

You want to change one page and test it before anybody else sees it. With APEXlang on 26.1 you have two options and both are not great. Import into the real app, and you overwrite it (everybody's work in it, not just your page). Or import into a plain copy under another id, and you get an app that has no idea where it came from: you can't easily compare it with the original, and half of your business logic breaks because the app id changed.



The old loop

Currently, I test every page in a plain copy of the app, one per job. It works, but look at what it costs:

  • the copy is a whole-app import, and so is the delivery into the real app afterwards
  • the copy has no link to the original, so "what did I change?" is a git diff, never something APEX can answer
  • the copy has its own application id, so everything keyed by the app id (settings, roles, translations, logs) misses
  • we need a freshness check before the real import, so we don't revert somebody else's work in main app

A working copy fixes three of these four out of the box. The fourth, the app id, takes a small change in your code.


What 26.2 gives you

APEX 26.2 shipped this week, and for the first time a script can use the third option.

The working copy API sits in APEX_APPLICATION_ADMIN. On 26.1 the only way to create a working copy outside the Builder was the internal WWV_FLOW_WORKING_COPY_DEV package, with no grant to anybody. I checked my local 26.2 instance and the new function is there, behind the public APEX_APPLICATION_ADMIN synonym:

FUNCTION APEX_APPLICATION_ADMIN.CREATE_WORKING_COPY (
    p_application_id            IN  NUMBER,
    p_working_copy_name         IN  VARCHAR2,
    p_working_copy_description  IN  VARCHAR2    DEFAULT NULL
)
RETURN NUMBER;


It returns the id of the new copy. A not unique app name for the same main app raises an error, so put your task or ticket number into the name. Shame we can't pick the application id, it would be more useful.

Two more 26.2 changes make it usable from git. APEXlang now keeps the working copy metadata on import.

And SQLcl "apex import" has a new -files argument, so you import just the files you changed. The order of the files does not matter, SQLcl sorts out the dependencies. A few limits, straight from the announcement: the application has to exist in the target workspace already; themes, templates, plug-ins and workspace components cannot be imported this way; and Oracle says it is meant for development and testing, not for production deployments.


The new loop

So here is the flow I want for every page task:

  • create a working copy of main app with the API, named after the task
  • export the working copy as APEXlang
  • change the .apx files you need and validate them offline
  • import only those files into the working copy and test it; repeat as often as you like
  • compare the copy with main app, merge into main app in the Builder
  • export main app and commit that export


Application id

This is the small change. The working copy is a different application with a different id. Anything keyed by the application id is looking for rows under an id that nobody seeded, so the copy runs, but it does not behave like your main app.

APEX has an answer for this, the MAIN_APP_ID substitution string. In a working copy it returns the id of main app; in any other app it returns the app's own id. All you have to do is to replace all APP_ID substitutions to MAIN_APP_ID. With APEXlang this should not be that difficult.

Fun fact, this is available from APEX 24.2.


Try it

If APEXlang itself is new to you, start with APEXlang is here.

If this saves your team one overwritten app, pass it on to whoever runs your APEX deployments.


Comments