Skip to content

Instantly share code, notes, and snippets.

@Plopix
Last active June 4, 2024 22:38
Show Gist options
  • Save Plopix/72851fd834395d154586b4ed2680310e to your computer and use it in GitHub Desktop.
Save Plopix/72851fd834395d154586b4ed2680310e to your computer and use it in GitHub Desktop.

Platform.sh to Upsun - Environment Variables migration script

The script assumes that you have the underlying permissions and that your shell is logged in.

Run the following in the project directory:

curl -fsSL https://gist.github.com/Plopix/72851fd834395d154586b4ed2680310e/raw/migrate-env-vars-from-platformsh-to-upsun.js | node - <source-cli>:<source-project-id>:<source-env> <target-cli>:<target-project-id>:<target-env>

Where:

  • *-cli: is the CLI of the service. Most likely: platform or upsun
  • *-project-id: is the Project ID of the service.
  • *-env: is the Env to grab/set the variables from/to

This script will fetch all the environment variables from the SOURCE and upsert them to the TARGET

License: MIT

Author:


</> with <3 for https://crystallize.com

#!/usr/bin/env node
const { exec } = require("child_process");
const sourceArg = (process.argv[2] || "").split(":");
const targetArg = (process.argv[3] || "").split(":");
const source = {
cli: sourceArg[0] || "platform",
projectId: sourceArg[1] || "",
env: sourceArg[2] || "main",
};
const target = {
cli: targetArg[0] || "upsun",
projectId: targetArg[1] || "",
env: targetArg[2] || "main",
};
if (!source.projectId || !target.projectId) {
console.error(
"Usage: migrate-env-vars-from-platformsh-to-upsun.js <source-cli>:<source-project-id>:<source-env> <target-cli>:<target-project-id>:<target-env>"
);
process.exit(1);
}
const shell_exec = (command) => {
return new Promise((resolve, reject) => {
exec(command, (err, stdout, stderr) => {
if (err || stderr) {
reject(err || stderr);
}
return resolve(stdout);
});
});
};
const curl = (service, options) =>
shell_exec(`${service.cli} p:curl -p ${service.projectId} ${options}`).then(
(stdout) => JSON.parse(stdout.trim())
);
const getEnvironmentVariableValue = (service, name) =>
shell_exec(
`${service.cli} ssh -p ${service.projectId} -e ${service.env} -- 'env' | grep "^${name}=" | awk -F '=' '{print substr($0, index($0, "=") + 1)}'`
)
.then((stdout) => stdout.trim())
.catch(() => "");
const buildNewVariable = (variable) => ({
name: variable.id,
attributes: variable.attributes,
is_json: variable.is_json,
is_sensitive: variable.is_sensitive,
visible_build: variable.visible_build,
visible_runtime: variable.visible_runtime,
is_enabled: variable.is_enabled,
is_inheritable: variable.is_inheritable,
});
const upsertVariable = async (service, value) => {
const endpoint = `environments/${service.env}/variables`;
const createResult = await curl(
service,
`-X POST ${endpoint} --json='${JSON.stringify(value)}'`
);
if (createResult.code === 409) {
const updateResult = await curl(
service,
`-X PATCH ${endpoint}/${value.name} --json='${JSON.stringify(value)}'`
);
if (updateResult.status === "error") {
console.error({
updateResult,
value,
});
throw new Error(`${updateResult.title} - ${updateResult.message}`);
}
console.log(`${value.name} has been updated.`);
return;
}
if (createResult.status === "error") {
console.error({
createResult,
value,
});
throw new Error(`${createResult.title} - ${createResult.message}`);
}
console.log(`${value.name} has been created.`);
return;
};
// MAIN
curl(source, "environments/main/variables").then((variables) => {
variables.forEach(async (variable) => {
if (!variable.id.startsWith("env:")) {
return;
}
const name = variable.id.split(":")[1];
let variablePayload = {
...buildNewVariable(variable),
value: variable.value,
};
if (variable.is_sensitive) {
variablePayload.value = await getEnvironmentVariableValue(source, name);
}
upsertVariable(target, variablePayload).catch((error) => {
console.error(`${name} has failed migration.`, error);
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment