Welcome to the Inedo Forums! Check out the Forums Guide for help getting started.

If you are experiencing any issues with the forum software, please visit the Contact Form on our website and let us know!

Custom Extension for Setting Variables



  • I'm trying to write a custom extension for reading a properties file which contains a list of (one per line) of "property=value" entries.

    I would like to create or modify buildmaster variables and set the value equal to that in the file.

    My question: how do I access the variables from the customs extension I am writing?

    So far I have got this (which admittedly isn't very much) and I cannot figure out from the SDK documenation how to access the internals of buildmaster.

    // -----------------------------------------------------------------------
    // <copyright file="VariableInject.cs" company="NZ Customs Service">
    // TODO: Update copyright text.
    // </copyright>
    // -----------------------------------------------------------------------

    namespace NZCustomsServiceExtension.Actions
    {
    using System;
    using System.Collections.Generic;
    using System.Text;
    using Inedo.BuildMaster;
    using Inedo.BuildMaster.Extensibility.Actions;

    /// <summary>
    /// Populate BuildMaster variables from a properties file.
    /// </summary>
    [ActionProperties(
        "Variable Injection",
        "Populates BuildMaster variables from a properties file.",
        "NZCustomsService")]
    public class VariableInject : ActionBase
    {
    
        /// <summary>
        /// Location of properties file
        /// </summary>
        [Persistent]
        public string PropertiesFile {get; set;}
    
        /// <summary>
        /// This method is called to execute the Action.
        /// </summary>
        protected override void Execute()
        {
            this.LogInformation("What do I do here???");
            
        }
        
        /// <summary>
        /// Returns a string displayed in the BuildMaster deployment plan
        /// </summary>
        /// <returns>
        /// A <see cref="System.String"/> that represents this instance.
        /// </returns>
        public override string ToString()
        {
            return string.Format("Read properties file {0}", this.PropertiesFile);
        }
    
    }
    

    }



  • Hi Andrew,

    The C# code to read the variables from a file be pretty simple...

    foreach (var line in File.ReadAllLines(filePath))
    {
    var parts = line.Split("=".ToCharArray(), 2);
    if (parts.Length != 2)
    {
    this.LogWarning(line + " is not in the varname=value format");
    continue;
    }
    this.Context.Variables[parts[0]] = parts[1];
    }

    But depending on how much you want to generalize "PATH TO FILE", it can be a bit more complicated. Easiest is to do a persistant property with the absolute path to the file on the buildmaster server.

    Alex



    1. I have a properties file containing:
      FRED=GEORGE
      BUILD_STUFF=fool

    And an existing buildmaster variable:
    BUILD_STUFF=a

    1. When I run the build it logs:
      Add FRED=GEORGE
      Update BUILD_STUFF=fool

    But in the next task where I echo:
    "BUILD_STUFF=%BUILD_STUFF%, FRED=%FRED%"

    I get:
    BUILD_STUFF=a, FRED=%FRED%

    1. And on the build page it lists the environment variables as:
      BUILD_STUFF = a
      and does not register the fact I've changed and added to them.

    Not surprised by point 3, but point 2 is a real problem. Do you know of a way around this?

    Current code:
    protected override void Execute()
    {
    try
    {
    foreach (var line in File.ReadAllLines(this.PropertiesFile))
    {
    var parts = line.Split("=".ToCharArray(), 2);
    if (parts.Length != 2)
    {
    this.LogWarning(line + " is not in the varname=value format");
    continue;
    }

                    if (this.Context.Variables.ContainsKey(parts[0]))
                    {
                        this.LogInformation("Update " + line);
                        this.Context.Variables[parts[0]] = parts[1];
                    }
                    else
                    {
                        this.LogInformation("Add " + line);
                        this.Context.Variables.Add(parts[0], parts[1]);
                    }
                }
            }
            catch (Exception ex)
            {
                this.LogError(ex.Message);
            }
        }


  • At the moment, build and promotion-level variables cannot be modified by an action during an execution. This is mainly because of the way default values are cascaded and inherited. We've talked about adding another variable scope (execution) that then is created and persisted only at execution time, which would then allow for this - but at the moment build/promotion variables are immutable once the build is created.

    You should still however be able to add variables during execution time - they just won't appear in the build summary. In a quick test I ran setting a variable that wasn't specified as a build variable worked later on in the execution with the code you have written, so I couldn't repro part 2. Make sure both the BuildMaster service and web app are restarted whenever the extension changes, otherwise changes might not actually be loaded by the extension loader.



Inedo Website HomeSupport HomeCode of ConductForums GuideDocumentation