Skip to content

Commit

Permalink
feat: add script + action to update extensibility
Browse files Browse the repository at this point in the history
  • Loading branch information
OS-martacarlos committed May 20, 2024
1 parent 95b491d commit 58f68cc
Show file tree
Hide file tree
Showing 5 changed files with 332 additions and 0 deletions.
46 changes: 46 additions & 0 deletions .github/workflows/o11_change_extensibility.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: (O11) Update Extensibility

on:
workflow_dispatch:
inputs:
tag:
description: 'The repo version tag'
required: true
default: '0.0.1'
forgeVersion:
description: 'The plugin version on the forge'
required: true
default: '0.0.1'
mabsMin:
description: 'Minimum MABS version'
required: true
default: '9.0.0'
enviroment:
description: 'O11 Enviorment'
required: true
default: enmobile11-dev.outsystemsenterprise.com
type: choice
options:
- enmobile11-dev.outsystemsenterprise.com
- enmobile11-tst.outsystemsenterprise.com
- enmobile11.outsystemsenterprise.com

jobs:
deploy:
name: Change OML Extensibility
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 18

- name: Install dependencies
run: npm install

- name: Update Extensibility Configurations JSON
run: npm run update:tag --plugin=BarcodeAutomation --name="Barcode Automation" --mabs=${{ github.event.inputs.mabsMin }} --environment=${{ github.event.inputs.enviroment }} --repository=${{ github.repository }} --forge=${{ github.event.inputs.forgeVersion }} --branch=${{ github.event.inputs.tag }} --authentication="${{ secrets.BASICAUTH }}"

43 changes: 43 additions & 0 deletions .github/workflows/o11_deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: (O11) Deploy Plugin

on:
pull_request:
workflow_dispatch:
inputs:
to:
description: 'Target O11 Enviorment'
required: true
default: qa
type: choice
options:
- Testing
- Production
from:
description: 'Source O11 Enviorment'
required: true
default: qa
type: choice
options:
- Development
- Testing


jobs:
deploy:
name: Deploy to ${{ github.event.inputs.to }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 18

- name: Install dependencies
run: npm install

- name: Deploying from DEV to TST
run: npm run deploy --plugin=BarcodeAutomation --from=Development --to=Testing --lifetime=${{ secrets.LIFETIME }} --authentication="${{ secrets.AUTOMATION_TOKEN }}"

11 changes: 11 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@
"cordova-android",
"cordova-ios"
],
"scripts": {
"update:tag": "node ./scripts/change-extensibility.js",
"deploy": "node ./scripts/deploy.js",
"bump:version:major": "node ./scripts/bump-version major",
"bump:version:minor": "node ./scripts/bump-version minor",
"bump:version:patch": "node ./scripts/bump-version patch",
"bump:version:pre": "node ./scripts/bump-version prerelease"
},
"devDependencies": {

},
"cordova": {
"id": "com.outsystems.plugins.barcode",
"platforms": [
Expand Down
68 changes: 68 additions & 0 deletions scripts/change-extensibility.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
if(!process.env.npm_config_plugin) {
throw new Error("Missing plugin name.");
}

let pluginSpaceName = process.env.npm_config_plugin;
let metadata = process.env.npm_config_name;
let pluginForgeVersion = process.env.npm_config_forge
let mabsMin = process.env.npm_config_mabs;

let repository = process.env.npm_config_repository;
let branch = process.env.npm_config_branch;

let environment = process.env.npm_config_environment;

if(process.env.npm_config_authentication == null) {
throw new Error("Missing authentication argument.");
}
let basicAuthentication = process.env.npm_config_authentication;

let url = "https://" + environment + "/CodeUpdater/rest/Bulk/ExtensabilityUpdate";

let extensibilityChangeJson = {
plugin :{
url: repository+"#"+branch,
},
metadata: {
"mabs-min": mabsMin ? mabsMin : "9.0.0",
name: metadata,
version: pluginForgeVersion
}
}

console.log(extensibilityChangeJson);
let extensibilityChangeString = JSON.stringify(extensibilityChangeJson);
let buffer = new Buffer.from(extensibilityChangeString);
let base64 = buffer.toString('base64');

let body = [{
"ModuleName": pluginSpaceName,
"Content": base64
}];

console.log(
"Started changing extensibility in module " + pluginSpaceName +
".\n -- Extensibility will be configured to: " + repository+"#"+branch +
`\n with forge version ${pluginForgeVersion} and mabs min ${mabsMin}` +
"\nin environment:" + environment
);



const response = fetch(url, {
method: "POST", // *GET, POST, PUT, DELETE, etc.
cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
credentials: "same-origin", // include, *same-origin, omit
headers: {
"Content-Type": "application/json",
Authorization: basicAuthentication
},
body: JSON.stringify(body), // body data type must match "Content-Type" header
}).then((res) => {
if(res.ok && res.status == 200)
console.log("Successfully updated OML");
else console.log(res)
})



164 changes: 164 additions & 0 deletions scripts/deploy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@

if(process.env.npm_config_from == null || process.env.npm_config_to == null) {
throw new Error("Missing repositoryURL, branch, environment arguments");
}

if(process.env.npm_config_authentication == null) {
throw new Error("Missing authentication argument");
}

let pluginSpaceName = process.env.npm_config_plugin;
let fromEnvironment = process.env.npm_config_from;
let toEnvironment = process.env.npm_config_to;
let basicAuthentication = process.env.npm_config_authentication;
let baseURL = process.env.npm_config_lifetime;

baseURL = `https://${baseURL}/lifetimeapi/rest/v2`;

startDeploy(baseURL, fromEnvironment, toEnvironment, pluginSpaceName, basicAuthentication);

async function startDeploy(baseURL, fromEnvironment, toEnvironment, pluginSpaceName, auth){
let fromKey = await getEnvironmentKey(baseURL, fromEnvironment, auth);
let toKey = await getEnvironmentKey(baseURL, toEnvironment, auth);

let pluginKey = await getAppKey(baseURL, pluginSpaceName, fromKey, auth)

let deploymentKey = createDeploymentPlan(baseURL, fromKey, toKey, pluginKey, auth);

//TODO: check for conflicts + slack message for approval if conflicts were found
await startDeployment(baseURL, deploymentKey, auth);

while(!isFinished(baseURL, deploymentKey, basicAuthentication)){
//we wait until it's finished
sleep(5000);
}

}

function sleep(milliseconds) {
const date = Date.now();
let currentDate = null;
do {
currentDate = Date.now();
} while (currentDate - date < milliseconds);
}

async function getEnvironmentKey(base, env, auth){
let url = `${base}/environments`;

let response = await fetch(url, {
method: 'GET',
headers: {
"Content-Type": "application/json",
Authorization: auth
}
})

if(response.ok && response.status == 200){
let list = await response.json();
return list.filter((detail) => detail.EnvironmentType == env)[0]
}
}

async function getAppKey(base, pluginSpaceName, inEnv, auth){
let url = `${base}/applicationss?IncludeEnvStatus=true`;

let response = await fetch(url, {
method: 'GET',
headers: {
"Content-Type": "application/json",
Authorization: auth
}
})

if(response.ok && response.status == 200){
let list = await response.json();
let app = list.filter((a) => a.name == pluginSpaceName);
return app.AppStatusInEnvs.filter((status) => status.EnvironmentKey == inEnv)[0]
}
}

async function createDeploymentPlan(base, fromEnv, toEnv, pluginKey, auth) {
let url = `${base}/deployments`
let body = {
Notes: "Deployment triggered by github workflow",
SourceEnvironmentKey: fromEnv,
TargetEnvironmentKey: toEnv,
ApplicationOperations:[
{
ApplicationVersionKey: pluginKey
}
]
};

const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: auth
},
body: JSON.stringify(body)
})
console.log(response)

if(response.ok && response.status == 200){
let res = await response.json()
console.log("Deployment Response:" + res);
return response.json();
}
}

async function startDeployment(base, deployKey, auth){
let url = `${base}/deployments/${deployKey}/start`

const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: auth
}
})
console.log(response)

if(response.ok && response.status == 202){
console.log("Deployment Started Successfully!");
}
}

async function isFinished(base, deployKey, auth) {
let url = `${base}/deployments/${deployKey}/status`;

let res = await fetch(url, {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: auth
}
})

if(res.ok && res.status == 200){
let status = await res.json()
if(status.DeploymentStatus == 'running'){
console.log("Still running...");
return false
}
if(status.DeploymentStatus == 'aborted'){

throw Error ("!! Deployment aborted !!");
}
if(status.DeploymentStatus == 'finished_with_errors'){
throw Error ("!! Something went wrong with the deployment: finished with errors. Please check lifetime !!");
}

if(status.DeploymentStatus == 'finished_with_warnings'){
console.log("Finished with warnings");
return true
}
if(status.DeploymentStatus == 'finished_successful'){
console.log("Finished with warnings");
return true
}

}
throw Error ("!! Something went wrong with the request: " + await res.json());
}

0 comments on commit 58f68cc

Please sign in to comment.