How To Access Azure Devops Variable In SPFx Solution – Part 2

Ahamed Fazil Buhari
 
Senior Developer
June 8, 2020
 
Rate this article
 
Views
817

This is the continuation of my previous article – How To Access Azure Devops Variable In SPFx Solution – Part 1, in this article lets see how we can access variable inside SPFx solution by modifying gulpfile.js 

Here we use definePlugin to access the declared variable name inside the solution and we replace the declared variable with the azure devops env variable value during build. To know more about definePlugin refer this article.

I use same name as I’ve used in azure devops variable so that its easy to replace its value during build. (otherwise we need to manually give variable name)

devops

And we altered the gulpfile.js so that it will fetch azure devops variable during build and replace it in definePlugin. Copy and replace the gulpfile.js file in your SPFx solution

"use strict";
const build = require("@microsoft/sp-build-web");
const webpack = require("webpack");
const request = require("request");
const minimist = require("minimist");
const fs = require("fs");

let envVariables = {};
build.addSuppression(
  `Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`
);

//#region Check and assign envv from az devops

const getEnvVariablesSubtask = build.subTask(
  "get-env-variables-subtask",
  () => {
    // Example: To get envv from Test: gulp serve --env tst OR gulp serve --env=tst
    const knownOptions = {
      string: "env",
      default: { env: process.env.NODE_ENV || "dev" },
    };

    const envOptions = minimist(process.argv.slice(2), knownOptions);
    let envv_url = "";
    if (envOptions && envOptions.env)

      switch (envOptions.env.toLowerCase()) {
        case "prd":
          console.log(
            "Getting ENVV for - ".blue,
            `${envOptions.env}`.green.bold
          );
          envv_url =
            "https://fazilsp.visualstudio.com/sppals/_apis/distributedtask/variablegroups?groupId=1";
          break;
        default:
          envv_url =
            "https://fazilsp.visualstudio.com/sppals/_apis/distributedtask/variablegroups?groupId=5";
          break;
      }
    // To know more about token generation - https://www.sharepointpals.com/post/how-to-access-azure-devops-variable-in-spfx-solution-part-1
    // The current token - devops_envv_access is generated by Fazil valid until: October 7th, 2020
    const options = {
      url: envv_url,
      headers: {
        Authorization:
          "Basic ZGV2bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxE=",
      },
    };

    return request(options, function (error, response, body) {
      if (!error && response.statusCode === 200) {
        console.log("Successfully fetched azure devops variables".green.bold);
        const response = JSON.parse(body);
        envVariables = response.variables;
      } else {
        console.log("Error while getting ENVV from Azure Devops".red.bold);
      }
    });
  }
);

const replaceEnvVariables = build.task(
  "replace-env-variables",
  getEnvVariablesSubtask
);

build.rig.addPreBuildTask(replaceEnvVariables);
build.configureWebpack.mergeConfig({
  additionalConfiguration: (generatedConfig) => {
    const solution_package = JSON.parse(fs.readFileSync("./package.json"));
    //Get Define Plugins
    let plugin, pluginDefine;
    for (let i = 0; i < generatedConfig.plugins.length; i++) {
      plugin = generatedConfig.plugins[i];
      if (plugin instanceof webpack.DefinePlugin) pluginDefine = plugin;
    }

    console.log("Running definePlugin".green.bold);
    const isDebugMode = pluginDefine.definitions.DEBUG;
    console.log(`IsDebugMode - `.blue, `${isDebugMode}`.green.bold);

    console.log(
      `Process Domain - `.blue,
      `${process.env.USERDOMAIN}`.green.bold
    );

    console.log("Replacing Env Variables".green.bold);
    let envPropertyNames = Object.getOwnPropertyNames(envVariables);
    if (envPropertyNames && envPropertyNames.length === 0)
      console.log("No Env Variable Found".red.bold);

    envPropertyNames.forEach((envPropName) => {
      console.log(
        `${envPropName}`.blue,
        `${envVariables[envPropName].value}`.green.bold
      );

      pluginDefine.definitions[envPropName] = JSON.stringify(
        envVariables[envPropName].value
      );
    });

    pluginDefine.definitions.WEBPART_NAME_ENVV = JSON.stringify(
      solution_package.name
    );

    pluginDefine.definitions.WEBPART_VERSION_ENVV = JSON.stringify(
      solution_package.version
    );

    return generatedConfig;
  },
});
//#endregion

build.initialize(require("gulp"));

Change the envv_url value as per your need and provide authorization value that we generated in the previous article –

devops7
And we added new argument called –env by default it will fetch DEV devops environment variable, if we want to get variable for PRD then we can run below script
gulp serve –env=prd

github code is available here. The key files gulpfile.js & webpack-definePlugin-variables.d.ts

Happy Coding

Fazil

Author Info

Ahamed Fazil Buhari
 
Senior Developer
 
Rate this article
 
Ahamed is a Senior Developer and he has very good experience in the field of Microsoft Technologies, especially SharePoint, Azure, M365, SPFx, .NET and client side scripting - JavaScript, TypeScript, ...read more
 

Leave a comment