Git Workflow for Vendor Branching

For maintaining a customized branch of uPortal. Useful for managing the changes needed for a deployment of uPortal while retaining the ability to quickly cherry-pick changes from mainline uPortal development and upgrade versions.

Local Clone

Keep in mind that all of the steps, procedures, and commands outlined on this page must occur in a local clone on your filesystem. You cannot perform these operations in the web UI on Github or Bitbucket.

Project Setup

See http://help.github.com/fork-a-repo/ for information on how to create a fork, clone it and add a reference to the https://github.com/Jasig/uPortal repository.

If your customizations will involve code or configuration changes you do not want to be public you either need to make your fork private or use a hosting solution other than GitHub to host your fork of Jasig/uPortal. These instructions all assume that origin is either public on GitHub or you have made the appropriate adjustments to make the origin repository private.

On This Page

Keeping Your Fork Up To Date

These instructions can be applied to any branch by replacing master with the name of the branch you're interested in keeping up to date, rel-3-2-patches for example. After performing these steps, both your local repo and your remote fork will be contain the latest changes from Apereo on the specified branch. This example, however, does not affect your Vendor Branch (see below). Be sure to read the remaining sections on this page for information on combining updates from Apereo with your local configuration, look-and-feel, and customizations.

# retrieve the updates from the upstream repository
$ git fetch upstream -p

# switch to the master branch
$ git checkout master
 
# merge the incoming changes into your local branch
$ git merge upstream/master

# now you're ready to update your fork
$ git push origin master

Never Commit to Master!

Or any other branch that exists in the https://github.com/Jasig/uPortal repository. If you do make a commit on a branch that is tracking a real uPortal branch and that commit is not accepted as part of a pull request you will be maintaining that customization for the rest of your fork's life. It is always better to not commit on project branches for a project that you do not have push access to and to use topic or vendor branches instead.

Create a Vendor Branch

Determine the tag you want to use as the basis for the work, for this example we will start with uportal-4.0.5

# create the vendor branch 'myschool-master' which is based on the tag 'uportal-4.0.5'
$ git checkout -b myschool-master uportal-4.0.5 
 
# push the new vendor branch to your fork
$ git push origin myschool-master

Customize the Vendor Branch

Follow the instructions on Git Workflow for Committers for committing to your vendor branch (replace references to master with myschool-master.

Customize your entity files

  1. Recursively copy uportal-war/src/main/data/quickstart_entities to your own institutional entities file, such as uportal-war/src/main/data/my_entities
    1. Remove the entities you don't want and add your own entities
  2. Edit build.properties to refer to your entity directory
    1. quickstart_entities.location=uportal-war/src/main/data/my_entities

Customize your tenant templates

If you are using the multi-tenancy capabilities of the portal, you'll want to have your own version of the tenant template files so you can customize them.

  1. Recursively copy uportal-war/src/main/resources/org/jasig/portal/tenants/data to your own location, such as uportal-war/src/main/resources/tenantTemplates
    1. Customize as appropriate
  2. Edit the portal.properties to refer to your tenant template directory
    1. org.jasig.portal.tenants.TemplateDataTenantOperationsListener.templateLocation=classpath:/tenantTemplates/**/*.xml

Alter project files to suit your configuration

  1. Alter the project files for your environment; e.g. update filters/*.properties, add LDAP or other sources to personDirectoryContext.xml, configure the authentication appropriately for your environment, etc.

Cherry-Pick Commits

The cherry-pick command can be used to merge specific commits from another branch into your vendor branch. This is useful for example if a specific bug is fixed for the next release but you need it now. You can cherry pick the commits involved in the fix into your vendor branch. Note that this is not fool proof and if the cherry-picked commits rely on a change made since the last release you have merged the merge might fail or uPortal may fail to work at runtime.

  1. Determine the commit ids you want to cherry-pick. Looking at the Commits tab in the Jira Issue should show you all commits that reference the Jira ID and serve as a good starting point to determine the IDs
  2. Run the cherry-pick command 

    # Follow the steps in Keeping Your Fork Up To Date
     
    # Merge in specific commits
    $ git cherry-pick 1a2b3c4d a1b2c3d4
     
    # Handle any merge errors that come up
    $ git mergetool -y
  3. Test the changes with a local build and deploy
  4. Push the changes 

    # push the changes to your fork
    $ git push origin

Upgrade to a New Release

Git can make upgrading to new releases much easier. Since all of the change history for your customizations and uPortal's development are available you only ever end up having to resolve real merge issues with very little noise. In this example we are upgrading to the uportal-4.3.0 tag.

  1. Merge the new tag 

    # Follow the steps in Keeping Your Fork Up To Date
     
    # Checkout your vendor branch
    $ git checkout myschool-master
     
    # Merge in the changes that have been made up to uportal-4.3.0.  
    # NOTE:  You don't specify upstream/uportal-4.3.0. That notation is for a branch not a tag. If you do something like upstream/uportal-4.3.0, you'll get an error message like
    # merge: upstream/uportal-4.3.0 - not something we can merge
    $ git merge uportal-4.3.0
  2. Handle Merge Conflicts 

    # Handle any merge errors that come up
    $ git mergetool -y
  3. Test the changes with a local build and deploy

Push the changes 

# push the changes to your fork
$ git push origin

 

Updating to newer version

Updating your code with changes from Apereo

Regardless of which approach you use to update your code (see section on Cherry-Pick Commits and Upgrade to New Release), there are some things you should do.

  1. Merge in the changes from Apereo (see related sections)
  2. Review the updates made to uportal-war/src/main/data, in particular those made to the quickstart_entitites (which you copied and customized).  Determine which changes you would like to incorporate into your customized entities directory.  Create a plan for updating those entities in your dev, test, and prod databases (see Importing and Exporting data for information on using ant data-import).  See more on that below.
  3. If you are using the multi-tenancy capabilities of the portal, review the updates made to uportal-war/src/main/resources/org/jasig/portal/tenants/sampledata and incorporate those you would like into your tenant template data set (typically you copy the sample tenant data to your own institution-specific folder and customize it).  Any existing tenants that were created from the previous data set may need to be updated.  See more on that below.

Updating your data with changes from Apereo

The database entities (in uportal-war/src/main/data) are broken into 3 tiers to theoretically allow for easier customization.  Required entities are to get the portal to run. Default entities are for basic portal functionality.  Quickstart entities are for a particular experience and are meant to be copied and customized for your institution. Some of the quickstart entities override the default entities, providing additional data such as categories and groups that are applicable to the portlets in the quickstart data set. The import/db-init process first processes all the required entities, then all the default entities, then all the quickstart entities (or institution-specific entities if you follow the recommended process) allowing later entities to override earlier entities.

Your institution-specific entities are derived from the quickstart data (typically copy the quickstart_entities folder to an institution-specific folder and you add, remove, or modify portlets, categories, groups, PAGS groups, etc. to suit a particular institution). When going from 4.2.0 to 4.3.0 (or any release to another release) look at what changed in the entity files and incorporate those changes into your institution-specific entities.  

  • Look at what has changed in required_entities and default_entities.  The git merge process described above will update these folders with the latest changes.  You'd need to look at what the changes were and incorporate those changes into your release process (typically importing new or updated entities, possibly doing ant data-delete or SQL to delete removed entities).
  • When an entity exists in both default and quickstart/your-institution entities you typically do not import the default entity. You'd look at 'what was changed in the default entity and should I incorporate that change into my institution-specific entity'. Actually you'd probably look at what the change was in the quickstart entity between the versions and incorporate that into your institution-specific entity; any change to the default entity was likely also made in the quickstart entity. 
  • You'd also want to look at what new additions or deletions of entities occurred in the required, default, and quickstart data. It's possible a new portlet was created and added to a layout providing new functionality you might want, as was done when the Search Launcher or notification icon was added to the header area, or what deletions occurred possibly indicating functionality change you'd want to be aware of.
  • You can easily see the differences with a good diff tool. A traditional diff tool that can handle directory-level diffing would work if you check out your current release into one directory and the new release into another and you can diff the uportal-war/src/main/data folders between the two. An IDE-based tool such as intelliJ or eclipse will visually allow you to compare your current git checkout to another git branch. Again you'd probably look at what changes occurred in the quickstart data folder between the two versions and incorporate the changes you want into your institution-specific entities. Leaving the quickstart folder in your project even though it is not used is very convenient when you want to upgrade to a newer version because it gives you a base of comparison to look for the changes from the community.

Updating Tenancy with changes from Apereo

If using the multi-tenancy capabilities of the portal, in addition to updating your code and regular entities, you might also need to update the tenant data.  If you followed the standard process, you copied the sample tenant data entity files from uportal-war/src/main/resources/org/jasig/portal/tenants/sampledata to your own institution-specific location such as uportal-war/src/main/resources/tenantdata and customized them, similar to what is done with the normal quickstart data.  Look at the changes made to uportal-war/src/main/resources/org/jasig/portal/tenants/sampledata and determine which changes you would like to include in your institution-specific tenant templates.  In addition, if you have existing tenants created from the previous tenant templates, you typically want to update the existing tenant data as well. To do this the general process is:

  1. Export all data using ant data-export.  The tenant data entities will be intermingled with the regular portal entities.
  2. Update the existing tenant's entity files
  3. Import the updates into the system.  This may be appropriate to do before or after a code update if you are trying to do zero-downtime deployments. You have to look at the changes and decide which approach is better.

Contributing Fixes/Features (New Work)

Say you've found a bug and want to contribute a fix. The easiest approach is to acknowledge that you want to contribute up front and follow these step.

  1. Follow the steps in Keeping Up To Date
  2. Create a topic branch from the latest merged uPortal tag, this prevents unexpected changes from getting merged later on

    # create branch 'UP-XXXX' based on tag 'uportal-4.0.5'
    $ git checkout -b UP-XXXX uportal-4.0.5
  3. Follow the steps in Git Workflow for Non-Committers - Making a Change to work on the topic branch and submit a pull request
  4. Once you've submitted the pull request (even better, after the pull request has been merged) merge the topic branch into your vendor branch

    # checkout vendor branch
    $ git checkout myschool-master
     
    # merge the topic branch
    $ git merge UP-XXXX
  5. Push the changes 

    # push the changes to your fork
    $ git push origin

Contributing Fixes/Features (Existing Work)

Say you've fixed a bug on your vendor branch and realize you should contribute the fix back to uPortal. It isn't too late! Follow these steps to see how.

  1. Follow the steps in Keeping Up To Date
  2. Create a topic branch from uPortal master

    # create branch 'UP-XXXX' based on 'master'
    $ git checkout -b UP-XXXX master
  3. Use cherry-pick to merge the specific commits for the fix/feature into the topic branch 

    # Merge in specific commits
    $ git cherry-pick 1a2b3c4d a1b2c3d4
     
    # Handle any merge errors that come up
    $ git mergetool -y
  4. Push your Topic Branch 

    # Push the branch to your fork for others to review
    $ git push origin UP-XXXX
  5. Follow http://help.github.com/send-pull-requests/ to make a pull request from your UP-XXXX topic branch to Jasig/uPortal