Skip to main content

APEX Deployment Tool - Automated patching

P

Patching is the most significant feature of ADT. You can do a lot of cool things in ADT, but patching is the coolest one. I call this automated patching, because typically I don't have to intervene and I can deploy a patch without any change.

The whole idea behind ADT is to focus on your job as a developer and don't worry about mundane tasks like creating patch files manually. ADT has many checks and features to give you confidence on deploying and time to focus on more important or interesting things.

ADT does not store anything in database and it does not need any objects in database either. The patch.py script gets all the information from your Git repo (folders, files and config file). To make this work, you must be using Git. Without Git repo you will not be able to generate patch files.


This is part of multiple ADT articles:


Lets talk about workflow

  • you will get a task/card to work on
  • you will add/change database objects and/or APEX pages/components as needed and in any tool you prefer; you can work with exported files, you can change database objects directly, you can work on your own instance, you can work on the shared one, you can work in a shared branch, you can work in yours, all of that is up to you
  • you will export database changes, possibly also data and commit your changes to Git; it really helps a lot to add the task/card number and a meaningful description to the commit summary (for release notes and for better orientation when searching for things and also you will be able to see related commits in Jira), you will use this task/card number later to identify which commits will be part of your patch; also keep in mind that you can commit just parts of the file and you can do unlimited number of commits
  • you will export recent APEX changes and commit your changes in Git; again with a proper task/card number
  • you will generate and deploy patch file for your next environment (typically UAT, INT, LAB3, however it is called in your company), so you can test your code there with proper data; to do that you will run patch.py and this little magic script will create a patch file for you

You can repeat any of these steps as many times as you need. Before deploying you can change any of the generated files. And you can deploy them via ADT, manually or via your CI/CD pipeline.


Features

The output of patch will be a list of matching commits, patch file in your patch folder and snapshot of each file in snapshots subfolder. The patch file will contain the overview at top so you can see what is planned, it will be enriched with prompts so you don't get lost while reading the logs, it would also contain the source of the files (commit numbers) so you can track it to the source.

There are several cool features built into the ADT to make your life as a developer (or release manager) easier. All your object changes will be sorted properly, so you don't have to worry about that (which also minimize invalidated objects). Grants for your APEX schema will be added automatically. Some other minor source modifications will happen, variables in templates will be replaced, ALTER statements in scripts will be wrapped into a repeatable blocks... And all your files will be copied to snapshots folder in the patch, so you have complete patch there. You can check it and you can change it before deployment.

You can specify patch templates which basically adds template files to specific points in each patch file (for example to setup NLS at start, recompile invalid objects before materialized views, or increase APEX app version after APEX deployment...). Basically anything you would include in every patch.

You can specify patch scripts for specific card numbers, these scripts will be added to a specific point in patch file, but just for this specific patch (typically used for ALTER statements after tables, data changes...), anything you need to add just once for a specific patch. If you delete object or alter table, ADT will generate a file for you in the patch_scripts folder. You have to take care of data changes only. Imagine that, you modify your table (anyhow you want) and you don't have to write the ALTER statements for the patch...

You can also specify which commits you want or don't want to be part of your patch (explore the -search, -commit, -ignore and -my options). You can list individual commits or you can provide ranges.

Multiple schemas are supported in a way. You can have database schema and you can have different APEX schema. If you have multiple database schemas, the dependencies are not resolved beyond each schema. Each APEX application will get its own patch file and if you prefer do deploy full application export (instead of changed pages/components), you can. There are plenty of config options available to customize patching, so it can be tailored to your individual needs. ADT also supports the replacing of existing pages and components.

If your patch can't be deployed right away, you are risking deployment issues later. Depending on your deployment strategy it might happen that you deploy a patch in different order. Imagine you change package in patch 1. And you modify same package in patch 2 and deploy patch 2 first. Later you decide to deploy patch 1 and that would lead to loss of changes made by patch 2. ADT will let you know when you are about to break something and give you more confidence to quickly move around.

Sometimes you just want to deploy older patch but with current files or even you local (uncommitted) files. You can do that too, you just add the -head or -local modifiers.

Some people name columns on views in the view definition and not on the query. I think this is really wrong and you should name columns correctly in the query itself. ADT will check this during the deployment and it will show you the warnings.

For APEX exports it will add some scripts around to setup workspace properly, install (actually replace) shared components first, pages last. It can change page creation/audit columns to match the patch code and date so you know by which patch was the page changed. Via templates you can also change the application version to current date and patch code, set requested authentication scheme (handy if you run different auth scheme on production), keep sessions alive... You can define any pre/post APEX scripts through patch template folder.

There are other features there, I don't remember them all. I will try to update this article later.


Examples

Overview

Show the help and available options:

adt patch

Show recent commits and/or patches (plus option to show just yours):

adt patch -target UAT -commits 50
adt patch -target UAT -commits 50 -my
adt patch -target UAT -patches 20
adt patch -target UAT -patches 20 -my

Patching

The main feature, create the patch base on task_id commits:

adt patch -target UAT -patch TASK_ID
adt patch -target UAT -patch TASK_ID -create

Create the patch base on task_id commits, but with exceptions (add or ignore specific commit numbers with numbers separated by spaces, you can also use ranges using dash), add -create when ready:

adt patch -target UAT -patch TASK_ID -commit # # #-# #-#
adt patch -target UAT -patch TASK_ID -ignore # # #-# #-#
adt patch -target UAT -patch TASK_ID -commit 1-20 30-32 35 36 -ignore 2 3 8-12 14-15 31

Use latest committed files or local files (including all uncommitted changes):

adt patch -target UAT -patch TASK_ID -head
adt patch -target UAT -patch TASK_ID -local

Create driving patch file above the patch folder:

adt patch -target UAT -patch TASK_ID -moveup

Create patch file based on commits from specific branch:

adt patch -target UAT -patch TASK_ID -branch NAME

Create patch file based on specific words in commit summary:

adt patch -target UAT -patch TASK_ID -search WORDS
adt patch -target UAT -patch TASK_ID -search %

Create patch with full application export (ignore changed pages/components):

adt patch -target UAT -patch TASK_ID -create -full

Deployment

Deploy patch to target or specific environment:

adt patch -target UAT  -patch TASK_ID -deploy
adt patch -target LAB3 -patch TASK_ID -deploy

If there are some errors during the deployment and you don't want to stop on them:

adt patch -target UAT -patch TASK_ID -deploy -continue

If you want to ignore some prechecks:

adt patch -target UAT -patch TASK_ID -deploy -force

Others

Rebuild the Git file (needed when you do some crazy things with your repo):

adt patch -target UAT -rebuild

It might happen that you will see tables in your schema ending with $1/$2, these are temp tables used to generate diff in between the tables and you can drop them:

adt patch -deldiff

There is also a small independent feature which allows you to merge files in specified folder into a single file:

adt patch -implode FOLDER


More on patch templates & scripts

You can create a patch template, which is a list of folders and files which will be added to each your patch at specific point, which depends on object type/group and timing (before, after). All files and subfolders will be sorted alphabetically. You can change the order of objects via the patch_map in your config file. Typically it would go in this order (and again, you can adjust this your config.yaml file):

patch_map:
    sequences:          # group name
        - SEQUENCE      # object type
    tables:
        - TABLE
    types:
        - TYPE
        - TYPE BODY
    synonyms:
        - SYNONYM
    objects:
        - VIEW
        - PROCEDURE
        - FUNCTION
        - PACKAGE
        - PACKAGE BODY
    triggers:
        - TRIGGER
    mviews:
        - MVIEW LOG
        - MATERIALIZED VIEW
    indexes:
        - INDEX
    data:
        - DATA
    grants:
        - GRANT
    jobs:
        - JOB

So in your patch_template folder you can create subfolders like tables/before/, tables_before/, before_tables/, tables/after/, tables_after/, after_tables/, after_objects/... You probably get it, right? The pattern is before or after combined with group name. Same logic is used for your patch_scripts/{$PATCH_CODE}/ folder. This way you can specify at which time point will your scripts be executed.


Issues

If you just change the objects grants and not the object itself, the grants will not make it to do patch. In that case, you can add your whole grant file to patch_scripts folder for the specific patch or into patch template for all patches. Revoked grants are not covered yet.

If you change just the comment on table and not the table itself, the comment will not make it to the patch.

Some objects are not supported (what you don't see on the patch_map above).

Some of the 23ai features might not be supported, but I plan to test my apps on 23ai soon.


Happy patching!


Comments