Version Control in Dynamics AX: Ensure that code changes are being made in model tied to version control

By Eric Meissner | April 3, 2017

Recently we ran into an issue where code changes were made in a model that was not tied to version control. When it came time to create a new build these changes weren’t included when the version control sync was executed. We had to take the time to move all of this code from one model to another and restart the build process. After this situation occurred a couple of times I decided to try to find a solution to help prevent this.

What I did was make a change to the class SysVersionControlSystem. This addition takes the version control folders from the XML definition file and compares them to the current model when AX is opened. If the current model doesn’t match a folder tied to version control it will return an error stating to change the model before making code changes. If this message does come up it is best to change the startup model in Tools – Options in the development tab. This is a pretty simple solution but could end up saving a lot of time if code changes are ever made in the incorrect model. It will also catch if a developer opens AX in a layer that is not tied to version control. Code screen shots are below.

NOTE: This was tested using Team Foundation Server. I did not test with Source depot or Visual SourceSafe but think it should work with them. I don’t think this would work with MorphX VCS since it uses AX database tables and doesn’t have a local repository folder.

Code review:
Created new method called ssi_ValidateCurrentModel. In method createModelsMap added call to new method (shown in first screenshot at end of method)

private void createModelsMap()
{
    MapEnumerator mapEnumerator;
    Filename modelFile;
    FilePath modelFilePath;
    FilePath modelFolder;
    SysVersionControlModelFile controllableModelFile;
    SysVersionControlSyncParameters syncParm;
    int line;
    boolean fileExists;

    mapEnumerator = modelFolders.getEnumerator();
    models = new Map(Types::Integer, Types::Class);
    aldLocations = new Map(Types::Integer, Types::String);

    // Iterate the folders
    while (mapEnumerator.moveNext())
    {
        modelFolder = mapEnumerator.currentKey();
        modelFilePath = strFmt(@'%1\%2', this.parmFolder(), modelFolder);
        modelFile = strFmt(@'%1\%2', modelFilePath, #ModelFileNameWithExtension);

        fileExists = System.IO.File::Exists(modelFile);

        // Read the model.xml file in each folder
        if (!fileExists)
        {
            // In case the file is in the VCS but not locally, force sync it
            line = infologLine();

            syncParm = SysVersionControlSyncParameters::construct();
            syncParm.parmSilent(true);
            syncParm.parmForce(true);

            controllableModelFile = SysVersionControlModelFile::construct();
            controllableModelFile.parmModelFolder(modelFile);

            this.commandSynchronize(controllableModelFile, syncParm);

            infolog.clear(line);

            fileExists = System.IO.File::Exists(modelFile);

            // Give warning if it still does not exists after a sync.
            if (!fileExists)
            {
                warning(strFmt("@SYS327410", modelFilePath));
            }
        }

        if (fileExists)
        {
            controllableModelFile = SysVersionControlModelFile::construct();
            controllableModelFile.fromFile(modelFile);
            this.addModelFolder(controllableModelFile);

            if (aldLocationsFromXML.exists(modelFolder))
            {
                aldLocations.insert(controllableModelFile.parmModelId(), aldLocationsFromXML.lookup(modelFolder));
            }
        }

        // BEGIN Version Control Model Check - 02/17/2017 - SSI EDM
        this.ssi_ValidateCurrentModel();
        // END Version Control Model Check - 02/17/2017 - SSI EDM
    }
}

/// <summary>
/// method that checks if startup model is tied to version control
/// </summary>
/// <remarks>
/// Version Control enhancements - 02/17/2017 - SSI EDM
/// </remarks>

private void ssi_ValidateCurrentModel()
{
    // NOTE: below logic was tested with TFS.  it should work with any version control that has a repository folder.
    // Visual SourceSafe and Source depot were not tested.

    boolean     tfsModel = false;
    modelName   tfsModelName;
    FilePath modelFolder;
    MapEnumerator mapEnumerator;
    ModelName   modelName;
    int currentModelId;

    // get current model id and set mapEnumerator
    currentModelId = xInfo::getCurrentModelId();
    mapEnumerator = modelFolders.getEnumerator();
    // remove spaces in folder name if any exists
    modelName = strRem(SysModelStore::modelId2Name(currentModelId), " ");

    // loop through version control folders
    while (mapEnumerator.moveNext())
    {
        modelFolder = mapEnumerator.currentKey();
        // remove spaces in folder name in case it was named with spaces in version control
        tfsModelName = strRem(modelFolder, " ");

        // compare current model name to version control model
        if (modelName == modelFolder)
        {
            // current model is tied to version control, exit loop
            tfsModel = true;
            break;
        }
    }

    // display error message if current model is not tied to version control
    if (!tfsModel)
    {
        //TODO: create label for message
        Error(strFmt("Current Model %1 is not tied to TFS.  Change model to %2 before making code changes", modelName, modelFolder));
    }

}


 

Related Posts

Recommended Reading:

5.13.22 Power Platform

Using Power BI Object Level Security

  The following article will demonstrate how to use Power BI Object Level Security to disable column data based on […]

Read the Article
5.12.22 Dynamics CRM

How to Use the Stoneridge Support Portal

Stoneridge Software’s support portal is an intuitive and useful function that makes it easy for you to access resources to […]

Read the Article
5.6.22 Dynamics GP

Dynamics GP Transaction Removal: Purchase Orders

  Are you having performance issues with Purchase Orders?  Do you find that there are old Purchase Orders on your […]

Read the Article
5.5.22 Dynamics GP

The Real Story about the Long-Term Future of Dynamics GP Support

I’ve seen a number of people put forward comment that Dynamics GP is going away and you have to get […]

Read the Article

New Features in Dynamics 365 Business Central 2022 Wave 1 Release Part 3 – Financial Enhancements

The Dynamics 365 Businses Central 2022 Wave 1 Release has a lot of new and exciting features to help your […]

Read the Article
4.29.22 Dynamics GP

Dynamics GP Transaction Removals: Bank Reconciliation

  This is part 2 of a 3 part series on Dynamics GP Transaction Removals. These quick tips will hopefully […]

Read the Article
4.28.22 Dynamics GP

Uncommonly Used Features – Integrate Purchasing and Payables to Fixed Assets in Dynamics GP

Being able to integrate Purchasing and Payables to Fixed Assets in Dynamics GP will help you create visibility for your […]

Read the Article

New Features in the Dynamics 365 Business Central 2022 Wave 1 Release Part 2 – Ease-of-Use Features

  There are many new features in the Dynamics 365 Business Central 2022 Wave 1 Release to get excited about! […]

Read the Article
4.22.22 Dynamics GP

Dynamics GP Transaction Removal Series: Receivables

  This is part 1 of a 3 part series on Dynamics GP Transaction Removal. These quick tips will hopefully […]

Read the Article

Start the Conversation

It’s our mission to help clients win. We’d love to talk to you about the right business solutions to help you achieve your goals.

Subscribe To Our Blog

Sign up to get periodic updates on the latest posts.

Thank you for subscribing!

X