AP OracleAPEXSourceControlStrategy
AP OracleAPEXSourceControlStrategy
Objective: Define the strategy the development team should use with regards to source control for all applications written with Oracle Application
Express.
I. Repository Structure
II. Developing, Committing Code, and Branching
The dev Branch:
Feature Branches
Merging Feature Branches into the Dev Branch
The test Branch:
The release Branch:
I. Repository Structure
Each APEX application will have a corresponding mercurial repository in Bitbucket. The repository should follow the below repository structure:
project-root
ddl/
dml/
packages/
snippets/
queries/
unit_tests/
scripts/
views/
f<<APP_ID>>.sql
00_install.sql
The explanation behind what each of these directories is for / what belongs in them is listed in the README.md file of the APEX - Test Repository
repo, but in case you have problems accessing that, we will also provide this explanation here:
README.md
# Author - Jeff Johnson (PDI)
# Date - 01.22.2019
######################################################################
# DDL #
######################################################################
* my_table.sql
######################################################################
# DML #
######################################################################
The DML directory should contain only scripts that populate tables,
including
the creation of scheduled jobs. Scripts here must be used for production
data fixes,
population of catalog/lookup tables, or creation of DBMS jobs. Any DML used
for populating dummy / test data should be stored in the snippets
directory.
* my_job.sql
declare
l_job_name varchar2 (250) := 'MY_JOB';
l_job_type varchar2 (250) := 'PLSQL_BLOCK';
l_job_action varchar2 (250) := 'BEGIN DBMS_OUTPUT.PUT_LINE
(''hello, world!''); END;';
l_start_date date := trunc (sysdate + 1) + .5/24;
l_repeat_interval varchar2 (250) := 'FREQ=DAILY';
l_end_date date := to_date (null);
l_job_class varchar2 (250) := 'DEFAULT_JOB_CLASS';
l_enabled boolean := true;
l_auto_drop boolean := false;
l_comments varchar2 (500) := 'My job!';
begin
begin
dbms_scheduler.drop_job (l_job_name);
exception
when others then
null;
end;
dbms_scheduler.create_job (
job_name => l_job_name,
job_type => l_job_type,
job_action => l_job_action,
start_date => l_start_date,
repeat_interval => l_repeat_interval,
end_date => l_end_date,
job_class => l_job_class,
enabled => l_enabled,
auto_drop => l_auto_drop,
comments => l_comments
);
exception
-- Raise unexpected error
when others then
raise_application_error (-20001, 'ERROR IN FILE dml/my_job.sql: COULD
NOT CREATE JOB FOR THE FOLLOWING REASON: ' || sqlerrm);
end;
######################################################################
# PACKAGES #
######################################################################
* my_package.pks
/****************************************************************
* Author - Jeff Johnson (PDI)
* Date - 01.22.2019
* Description - My package!
*
* Change Log
*
* Author Date Description
* --------- ------------- --------------------
* Jeff Johnson (PDI) 01.22.2019 Package Creation
***************************************************************/
/*
Author - Jeff Johnson (PDI)
Date - 01.22.2019
Description - Prints an input message
*/
procedure my_procedure (
p_message in varchar2
);
end;
* my_package.pkb
procedure my_procedure (
p_message in varchar2
)
as
begin
dbms_output.put_line (p_message);
end my_procedure;
end;
######################################################################
# SNIPPETS #
######################################################################
Snippets are used for production ready scripts and unit tests (for non-
production use) / misc non production code.
Within this directory are three subdirectories, "scripts", "queries", and
"unit_tests":
Scripts:
Should include production ready scripts that are to be run in
production
Queries:
Should include .sql files that can be re-used to help speed up
development.
Unit_tests:
Should include .sql files meant for unit testing PL/SQL procedures in
developed packages.
* ./scripts/my_script.sql
* ./queries/my_query.sql
with
my_in_memory_table
as (
select 1 my_column
from dual
)
select my_in_memory_table.my_column
from my_in_memory_table;
* ./unit_tests/my_package/my_procedure/1.sql
######################################################################
# VIEWS #
######################################################################
* my_view.sql
######################################################################
# 00_INSTALL.SQL #
######################################################################
This script should include * all * code required for a production release,
which should include all packages, all views, all DBMS_JOBS, and any
*NEW* DDL or DML scripts.
All views, packages, and jobs, whether or not they have been changed,
should be
re-runnable in production. This reduces the complexity of maintaining the
install script over time.
1 - DDL
2 - Package Specs
3 - Views
4 - Package Bodies
5 - DML
6 - APEX application file
7 - Snippets/Scripts
* 00_install.sql
@@"ddl/my_table";
-- START NOTES: THESE MAY GROW / MORE MAY BE ADDED, BUT NOTHING SHOULD BE
REMOVED UNLESS DEPRECATED
@@"packages/my_package.pks";
@@"views/my_view";
@@"packages/my_package.pkb";
@@"dml/my_job";
-- END NOTES
@@"snippets/scripts/my_script";
Feature Branches
The maintenance of the DEV branch should be the primary focus of the development team. This branch should always maintain a set of working
code comprising multiple features / fixes not yet migrated to the TEST environment. For each feature / small set of features that gets worked on
by an individual, we should create a branch off of the dev branch and name it according to the work that will be done. The steps to do this are as
follows:
Pull Requests
Now your code should be ready to be merged into the Dev branch. Log into Bitbucket and navigate to your repository. Then, click the "Pull
Request" tab, and create a pull request:
Pull Requests
When creating a pull request, Bitbucket should automatically select your source branch (it should know what your latest modified branch was -
this is tied to your account); nonetheless you should select your feature / fix branch as the source branch and the "dev" branch as the destination
branch. This will create a request to merge your branch into the dev branch, appending your features / fixes:
Also note that the "Close branch" checkbox is checked. For only our own feature / fixes branches, we should always check this box. This
will result in this branch being closed / destroyed once the merge to dev has been completed, which helps keep the repository relatively clean. We
should never elect to do this when merging dev into test or test into release via pull requests, but the development team should never
need to worry about making these pull requests.
After the pull request has been made, a reviewer / lead should be contacted, and that person should review the contents of the pull request and
approve it: