projen
Version:
CDK for software projects
106 lines • 18.3 kB
JavaScript
;
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PullRequestBackport = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const auto_approve_1 = require("./auto-approve");
const github_1 = require("./github");
const workflows_1 = require("./workflows");
const component_1 = require("../component");
const json_1 = require("../json");
const release_1 = require("../release");
class PullRequestBackport extends component_1.Component {
constructor(scope, options = {}) {
super(scope);
const workflowEngine = github_1.GitHub.of(this.project);
if (!workflowEngine) {
throw new Error(`Cannot add ${new.target.name} to project without GitHub enabled. Please enable GitHub for this project.`);
}
const branches = options.branches ?? release_1.Release.of(this.project)?.branches ?? [];
if (branches.length === 0) {
this.project.logger.warn("PullRequestBackport could not find any target branches. Backports will not be available. Please add release branches or configure `branches` manually.");
}
const targetPrLabelsRaw = options.backportPRLabels ?? ["backport"];
const targetPrLabels = [...targetPrLabelsRaw];
const shouldAutoApprove = options.autoApproveBackport ?? true;
if (shouldAutoApprove) {
const autoApprove = this.project.components.find((c) => c instanceof auto_approve_1.AutoApprove);
if (autoApprove?.label) {
targetPrLabels.push(autoApprove.label);
}
}
const backportBranchNamePrefix = options.backportBranchNamePrefix ?? "backport/";
const labelPrefix = options.labelPrefix ?? "backport-to-";
// Configuration
this.file = new json_1.JsonFile(this, ".backportrc.json", {
obj: {
commitConflicts: options.createWithConflicts ?? true,
targetPRLabels: targetPrLabels,
backportBranchName: `${backportBranchNamePrefix}{{targetBranch}}-{{refValues}}`,
prTitle: "{{sourcePullRequest.title}} (backport #{{sourcePullRequest.number}})",
targetBranchChoices: branches,
},
// File needs to be available to the GitHub Workflow
committed: true,
});
this.project.addPackageIgnore(this.file.path);
// Workflow
this.workflow = new workflows_1.GithubWorkflow(workflowEngine, options.workflowName ?? "backport");
this.workflow.on({
pullRequestTarget: {
types: ["labeled", "unlabeled", "closed"],
},
});
// condition to detect if the PR is a backport PR
// we prefer to match the PR using labels, but will fallback to matching the branch name prefix
const branchCondition = `startsWith(github.head_ref, '${backportBranchNamePrefix}')`;
const labelConditions = targetPrLabelsRaw.map((label) => `contains(github.event.pull_request.labels.*.name, '${label}')`);
const isBackportPr = labelConditions.length
? `(${labelConditions.join(" && ")})`
: `${branchCondition})`;
const checkStep = "check_labels";
const checkOutput = "matched";
const labelPrefixEscaped = labelPrefix.replace(/"/g, '\\"');
const credentials = workflowEngine.projenCredentials;
this.workflow.addJob("backport", {
name: "Backport PR",
runsOn: ["ubuntu-latest"],
permissions: {},
// Only ever run this job if the PR is merged and not a backport PR itself
if: `github.event.pull_request.merged == true && !${isBackportPr}`,
environment: credentials.environment,
steps: [
...credentials.setupSteps,
// We need a custom step to check if the PR has any of the labels that indicate that the PR should be backported.
// This is not currently possible with GH Actions expression by itself, so we use a bash script.
{
id: checkStep,
name: "Check for backport labels",
shell: "bash",
run: [
"labels='${{ toJSON(github.event.pull_request.labels.*.name) }}'",
`matched=$(echo $labels | jq '.|map(select(startswith("${labelPrefixEscaped}"))) | length')`,
`echo "${checkOutput}=$matched"`,
`echo "${checkOutput}=$matched" >> $GITHUB_OUTPUT`,
].join("\n"),
},
{
name: "Backport Action",
uses: "sqren/backport-github-action@v11.0.0",
// only run this step if we have found matching labels in the previous step
// this is to prevent workflow failures because the action fails when pre-conditions are not met
// and causes any PR to be marked with a red X, leading to error blindness.
if: `fromJSON(steps.${checkStep}.outputs.${checkOutput}) > 0`,
with: {
github_token: credentials.tokenRef,
auto_backport_label_prefix: labelPrefix,
},
},
],
});
}
}
exports.PullRequestBackport = PullRequestBackport;
_a = JSII_RTTI_SYMBOL_1;
PullRequestBackport[_a] = { fqn: "projen.github.PullRequestBackport", version: "0.99.51" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVsbC1yZXF1ZXN0LWJhY2twb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2dpdGh1Yi9wdWxsLXJlcXVlc3QtYmFja3BvcnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFDQSxpREFBNkM7QUFDN0MscUNBQWtDO0FBQ2xDLDJDQUE2QztBQUM3Qyw0Q0FBeUM7QUFDekMsa0NBQW1DO0FBQ25DLHdDQUFxQztBQTBEckMsTUFBYSxtQkFBb0IsU0FBUSxxQkFBUztJQUloRCxZQUNFLEtBQWlCLEVBQ2pCLFVBQXNDLEVBQUU7UUFFeEMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRWIsTUFBTSxjQUFjLEdBQUcsZUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3BCLE1BQU0sSUFBSSxLQUFLLENBQ2IsY0FDRSxHQUFHLENBQUMsTUFBTSxDQUFDLElBQ2IsNEVBQTRFLENBQzdFLENBQUM7UUFDSixDQUFDO1FBRUQsTUFBTSxRQUFRLEdBQ1osT0FBTyxDQUFDLFFBQVEsSUFBSSxpQkFBTyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBYyxDQUFDLEVBQUUsUUFBUSxJQUFJLEVBQUUsQ0FBQztRQUN0RSxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUN0Qix3SkFBd0osQ0FDekosQ0FBQztRQUNKLENBQUM7UUFFRCxNQUFNLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ25FLE1BQU0sY0FBYyxHQUFHLENBQUMsR0FBRyxpQkFBaUIsQ0FBQyxDQUFDO1FBRTlDLE1BQU0saUJBQWlCLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixJQUFJLElBQUksQ0FBQztRQUM5RCxJ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QkFBaUI7d0JBQzVGLFNBQVMsV0FBVyxZQUFZO3dCQUNoQyxTQUFTLFdBQVcsOEJBQThCO3FCQUNuRCxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7aUJBQ2I7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLGlCQUFpQjtvQkFDdkIsSUFBSSxFQUFFLHNDQUFzQztvQkFDNUMsMkVBQTJFO29CQUMzRSxnR0FBZ0c7b0JBQ2hHLDJFQUEyRTtvQkFDM0UsRUFBRSxFQUFFLGtCQUFrQixTQUFTLFlBQVksV0FBVyxPQUFPO29CQUM3RCxJQUFJLEVBQUU7d0JBQ0osWUFBWSxFQUFFLFdBQVcsQ0FBQyxRQUFRO3dCQUNsQywwQkFBMEIsRUFBRSxXQUFXO3FCQUN4QztpQkFDRjthQUNGO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs7QUExSEgsa0RBMkhDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBJQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IEF1dG9BcHByb3ZlIH0gZnJvbSBcIi4vYXV0by1hcHByb3ZlXCI7XG5pbXBvcnQgeyBHaXRIdWIgfSBmcm9tIFwiLi9naXRodWJcIjtcbmltcG9ydCB7IEdpdGh1YldvcmtmbG93IH0gZnJvbSBcIi4vd29ya2Zsb3dzXCI7XG5pbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tIFwiLi4vY29tcG9uZW50XCI7XG5pbXBvcnQgeyBKc29uRmlsZSB9IGZyb20gXCIuLi9qc29uXCI7XG5pbXBvcnQgeyBSZWxlYXNlIH0gZnJvbSBcIi4uL3JlbGVhc2VcIjtcblxuZXhwb3J0IGludGVyZmFjZSBQdWxsUmVxdWVzdEJhY2twb3J0T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgd29ya2Zsb3cuXG4gICAqXG4gICAqIEBkZWZhdWx0IFwiYmFja3BvcnRcIlxuICAgKi9cbiAgcmVhZG9ubHkgd29ya2Zsb3dOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTaG91bGQgdGhpcyBjcmVhdGVkIEJhY2twb3J0IFBScyB3aXRoIGNvbmZsaWN0cy5cbiAgICpcbiAgICogQ29uZmxpY3RzIHdpbGwgaGF2ZSB0byBiZSByZXNvbHZlZCBtYW51YWxseSwgYnV0IGEgUFIgaXMgYWx3YXlzIGNyZWF0ZWQuXG4gICAqIFNldCB0byBgZmFsc2VgIHRvIHByZXZlbnQgdGhlIGJhY2twb3J0IFBSIGZyb20gYmVpbmcgY3JlYXRlZCBpZiB0aGVyZSBhcmUgY29uZmxpY3RzLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBjcmVhdGVXaXRoQ29uZmxpY3RzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIGxhYmVscyBhZGRlZCB0byB0aGUgY3JlYXRlZCBiYWNrcG9ydCBQUi5cbiAgICpcbiAgICogQGRlZmF1bHQgW1wiYmFja3BvcnRcIl1cbiAgICovXG4gIHJlYWRvbmx5IGJhY2twb3J0UFJMYWJlbHM/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogVGhlIHByZWZpeCB1c2VkIHRvIG5hbWUgYmFja3BvcnQgYnJhbmNoZXMuXG4gICAqXG4gICAqIE1ha2Ugc3VyZSB0byBpbmNsdWRlIGEgc2VwYXJhdG9yIGF0IHRoZSBlbmQgbGlrZSBgL2Agb3IgYF9gLlxuICAgKlxuICAgKiBAZGVmYXVsdCBcImJhY2twb3J0L1wiXG4gICAqL1xuICByZWFkb25seSBiYWNrcG9ydEJyYW5jaE5hbWVQcmVmaXg/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEF1dG9tYXRpY2FsbHkgYXBwcm92ZSBiYWNrcG9ydCBQUnMgaWYgdGhlICdhdXRvIGFwcHJvdmUnIHdvcmtmbG93IGlzIGF2YWlsYWJsZS5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgYXV0b0FwcHJvdmVCYWNrcG9ydD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIExpc3Qgb2YgYnJhbmNoZXMgdGhhdCBjYW4gYmUgYSB0YXJnZXQgZm9yIGJhY2twb3J0c1xuICAgKlxuICAgKiBAZGVmYXVsdCAtIGFsbG93IGJhY2twb3J0cyB0byBhbGwgcmVsZWFzZSBicmFuY2hlc1xuICAgKi9cbiAgcmVhZG9ubHkgYnJhbmNoZXM/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogVGhlIHByZWZpeCB1c2VkIHRvIGRldGVjdCBQUnMgdGhhdCBzaG91bGQgYmUgYmFja3BvcnRlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgXCJiYWNrcG9ydC10by1cIlxuICAgKi9cbiAgcmVhZG9ubHkgbGFiZWxQcmVmaXg/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBQdWxsUmVxdWVzdEJhY2twb3J0IGV4dGVuZHMgQ29tcG9uZW50IHtcbiAgcHVibGljIHJlYWRvbmx5IGZpbGU6IEpzb25GaWxlO1xuICBwdWJsaWMgcmVhZG9ubHkgd29ya2Zsb3c6IEdpdGh1YldvcmtmbG93O1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihcbiAgICBzY29wZTogSUNvbnN0cnVjdCxcbiAgICBvcHRpb25zOiBQdWxsUmVxdWVzdEJhY2twb3J0T3B0aW9ucyA9IHt9LFxuICApIHtcbiAgICBzdXBlcihzY29wZSk7XG5cbiAgICBjb25zdCB3b3JrZmxvd0VuZ2luZSA9IEdpdEh1Yi5vZih0aGlzLnByb2plY3QpO1xuICAgIGlmICghd29ya2Zsb3dFbmdpbmUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYENhbm5vdCBhZGQgJHtcbiAgICAgICAgICBuZXcudGFyZ2V0Lm5hbWVcbiAgICAgICAgfSB0byBwcm9qZWN0IHdpdGhvdXQgR2l0SHViIGVuYWJsZWQuIFBsZWFzZSBlbmFibGUgR2l0SHViIGZvciB0aGlzIHByb2plY3QuYCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgYnJhbmNoZXMgPVxuICAgICAgb3B0aW9ucy5icmFuY2hlcyA/PyBSZWxlYXNlLm9mKHRoaXMucHJvamVjdCBhcyBhbnkpPy5icmFuY2hlcyA/PyBbXTtcbiAgICBpZiAoYnJhbmNoZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLnByb2plY3QubG9nZ2VyLndhcm4oXG4gICAgICAgIFwiUHVsbFJlcXVlc3RCYWNrcG9ydCBjb3VsZCBub3QgZmluZCBhbnkgdGFyZ2V0IGJyYW5jaGVzLiBCYWNrcG9ydHMgd2lsbCBub3QgYmUgYXZhaWxhYmxlLiBQbGVhc2UgYWRkIHJlbGVhc2UgYnJhbmNoZXMgb3IgY29uZmlndXJlIGBicmFuY2hlc2AgbWFudWFsbHkuXCIsXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHRhcmdldFByTGFiZWxzUmF3ID0gb3B0aW9ucy5iYWNrcG9ydFBSTGFiZWxzID8/IFtcImJhY2twb3J0XCJdO1xuICAgIGNvbnN0IHRhcmdldFByTGFiZWxzID0gWy4uLnRhcmdldFByTGFiZWxzUmF3XTtcblxuICAgIGNvbnN0IHNob3VsZEF1dG9BcHByb3ZlID0gb3B0aW9ucy5hdXRvQXBwcm92ZUJhY2twb3J0ID8/IHRydWU7XG4gICAgaWYgKHNob3VsZEF1dG9BcHByb3ZlKSB7XG4gICAgICBjb25zdCBhdXRvQXBwcm92ZSA9IHRoaXMucHJvamVjdC5jb21wb25lbnRzLmZpbmQoXG4gICAgICAgIChjKTogYyBpcyBBdXRvQXBwcm92ZSA9PiBjIGluc3RhbmNlb2YgQXV0b0FwcHJvdmUsXG4gICAgICApO1xuICAgICAgaWYgKGF1dG9BcHByb3ZlPy5sYWJlbCkge1xuICAgICAgICB0YXJnZXRQckxhYmVscy5wdXNoKGF1dG9BcHByb3ZlLmxhYmVsKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBiYWNrcG9ydEJyYW5jaE5hbWVQcmVmaXggPVxuICAgICAgb3B0aW9ucy5iYWNrcG9ydEJyYW5jaE5hbWVQcmVmaXggPz8gXCJiYWNrcG9ydC9cIjtcbiAgICBjb25zdCBsYWJlbFByZWZpeCA9IG9wdGlvbnMubGFiZWxQcmVmaXggPz8gXCJiYWNrcG9ydC10by1cIjtcblxuICAgIC8vIENvbmZpZ3VyYXRpb25cbiAgICB0aGlzLmZpbGUgPSBuZXcgSnNvbkZpbGUodGhpcywgXCIuYmFja3BvcnRyYy5qc29uXCIsIHtcbiAgICAgIG9iajoge1xuICAgICAgICBjb21taXRDb25mbGljdHM6IG9wdGlvbnMuY3JlYXRlV2l0aENvbmZsaWN0cyA/PyB0cnVlLFxuICAgICAgICB0YXJnZXRQUkxhYmVsczogdGFyZ2V0UHJMYWJlbHMsXG4gICAgICAgIGJhY2twb3J0QnJhbmNoTmFtZTogYCR7YmFja3BvcnRCcmFuY2hOYW1lUHJlZml4fXt7dGFyZ2V0QnJhbmNofX0te3tyZWZWYWx1ZXN9fWAsXG4gICAgICAgIHByVGl0bGU6XG4gICAgICAgICAgXCJ7e3NvdXJjZVB1bGxSZXF1ZXN0LnRpdGxlfX0gKGJhY2twb3J0ICN7e3NvdXJjZVB1bGxSZXF1ZXN0Lm51bWJlcn19KVwiLFxuICAgICAgICB0YXJnZXRCcmFuY2hDaG9pY2VzOiBicmFuY2hlcyxcbiAgICAgIH0sXG4gICAgICAvLyBGaWxlIG5lZWRzIHRvIGJlIGF2YWlsYWJsZSB0byB0aGUgR2l0SHViIFdvcmtmbG93XG4gICAgICBjb21taXR0ZWQ6IHRydWUsXG4gICAgfSk7XG4gICAgdGhpcy5wcm9qZWN0LmFkZFBhY2thZ2VJZ25vcmUodGhpcy5maWxlLnBhdGgpO1xuXG4gICAgLy8gV29ya2Zsb3dcbiAgICB0aGlzLndvcmtmbG93ID0gbmV3IEdpdGh1YldvcmtmbG93KFxuICAgICAgd29ya2Zsb3dFbmdpbmUsXG4gICAgICBvcHRpb25zLndvcmtmbG93TmFtZSA/PyBcImJhY2twb3J0XCIsXG4gICAgKTtcbiAgICB0aGlzLndvcmtmbG93Lm9uKHtcbiAgICAgIHB1bGxSZXF1ZXN0VGFyZ2V0OiB7XG4gICAgICAgIHR5cGVzOiBbXCJsYWJlbGVkXCIsIFwidW5sYWJlbGVkXCIsIFwiY2xvc2VkXCJdLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8vIGNvbmRpdGlvbiB0byBkZXRlY3QgaWYgdGhlIFBSIGlzIGEgYmFja3BvcnQgUFJcbiAgICAvLyB3ZSBwcmVmZXIgdG8gbWF0Y2ggdGhlIFBSIHVzaW5nIGxhYmVscywgYnV0IHdpbGwgZmFsbGJhY2sgdG8gbWF0Y2hpbmcgdGhlIGJyYW5jaCBuYW1lIHByZWZpeFxuICAgIGNvbnN0IGJyYW5jaENvbmRpdGlvbiA9IGBzdGFydHNXaXRoKGdpdGh1Yi5oZWFkX3JlZiwgJyR7YmFja3BvcnRCcmFuY2hOYW1lUHJlZml4fScpYDtcbiAgICBjb25zdCBsYWJlbENvbmRpdGlvbnM6IHN0cmluZ1tdID0gdGFyZ2V0UHJMYWJlbHNSYXcubWFwKFxuICAgICAgKGxhYmVsKSA9PlxuICAgICAgICBgY29udGFpbnMoZ2l0aHViLmV2ZW50LnB1bGxfcmVxdWVzdC5sYWJlbHMuKi5uYW1lLCAnJHtsYWJlbH0nKWAsXG4gICAgKTtcbiAgICBjb25zdCBpc0JhY2twb3J0UHIgPSBsYWJlbENvbmRpdGlvbnMubGVuZ3RoXG4gICAgICA/IGAoJHtsYWJlbENvbmRpdGlvbnMuam9pbihcIiAmJiBcIil9KWBcbiAgICAgIDogYCR7YnJhbmNoQ29uZGl0aW9ufSlgO1xuXG4gICAgY29uc3QgY2hlY2tTdGVwID0gXCJjaGVja19sYWJlbHNcIjtcbiAgICBjb25zdCBjaGVja091dHB1dCA9IFwibWF0Y2hlZFwiO1xuICAgIGNvbnN0IGxhYmVsUHJlZml4RXNjYXBlZCA9IGxhYmVsUHJlZml4LnJlcGxhY2UoL1wiL2csICdcXFxcXCInKTtcbiAgICBjb25zdCBjcmVkZW50aWFscyA9IHdvcmtmbG93RW5naW5lLnByb2plbkNyZWRlbnRpYWxzO1xuXG4gICAgdGhpcy53b3JrZmxvdy5hZGRKb2IoXCJiYWNrcG9ydFwiLCB7XG4gICAgICBuYW1lOiBcIkJhY2twb3J0IFBSXCIsXG4gICAgICBydW5zT246IFtcInVidW50dS1sYXRlc3RcIl0sXG4gICAgICBwZXJtaXNzaW9uczoge30sXG4gICAgICAvLyBPbmx5IGV2ZXIgcnVuIHRoaXMgam9iIGlmIHRoZSBQUiBpcyBtZXJnZWQgYW5kIG5vdCBhIGJhY2twb3J0IFBSIGl0c2VsZlxuICAgICAgaWY6IGBnaXRodWIuZXZlbnQucHVsbF9yZXF1ZXN0Lm1lcmdlZCA9PSB0cnVlICYmICEke2lzQmFja3BvcnRQcn1gLFxuICAgICAgZW52aXJvbm1lbnQ6IGNyZWRlbnRpYWxzLmVudmlyb25tZW50LFxuICAgICAgc3RlcHM6IFtcbiAgICAgICAgLi4uY3JlZGVudGlhbHMuc2V0dXBTdGVwcyxcbiAgICAgICAgLy8gV2UgbmVlZCBhIGN1c3RvbSBzdGVwIHRvIGNoZWNrIGlmIHRoZSBQUiBoYXMgYW55IG9mIHRoZSBsYWJlbHMgdGhhdCBpbmRpY2F0ZSB0aGF0IHRoZSBQUiBzaG91bGQgYmUgYmFja3BvcnRlZC5cbiAgICAgICAgLy8gVGhpcyBpcyBub3QgY3VycmVudGx5IHBvc3NpYmxlIHdpdGggR0ggQWN0aW9ucyBleHByZXNzaW9uIGJ5IGl0c2VsZiwgc28gd2UgdXNlIGEgYmFzaCBzY3JpcHQuXG4gICAgICAgIHtcbiAgICAgICAgICBpZDogY2hlY2tTdGVwLFxuICAgICAgICAgIG5hbWU6IFwiQ2hlY2sgZm9yIGJhY2twb3J0IGxhYmVsc1wiLFxuICAgICAgICAgIHNoZWxsOiBcImJhc2hcIixcbiAgICAgICAgICBydW46IFtcbiAgICAgICAgICAgIFwibGFiZWxzPScke3sgdG9KU09OKGdpdGh1Yi5ldmVudC5wdWxsX3JlcXVlc3QubGFiZWxzLioubmFtZSkgfX0nXCIsXG4gICAgICAgICAgICBgbWF0Y2hlZD0kKGVjaG8gJGxhYmVscyB8IGpxICcufG1hcChzZWxlY3Qoc3RhcnRzd2l0aChcIiR7bGFiZWxQcmVmaXhFc2NhcGVkfVwiKSkpIHwgbGVuZ3RoJylgLFxuICAgICAgICAgICAgYGVjaG8gXCIke2NoZWNrT3V0cHV0fT0kbWF0Y2hlZFwiYCxcbiAgICAgICAgICAgIGBlY2hvIFwiJHtjaGVja091dHB1dH09JG1hdGNoZWRcIiA+PiAkR0lUSFVCX09VVFBVVGAsXG4gICAgICAgICAgXS5qb2luKFwiXFxuXCIpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJCYWNrcG9ydCBBY3Rpb25cIixcbiAgICAgICAgICB1c2VzOiBcInNxcmVuL2JhY2twb3J0LWdpdGh1Yi1hY3Rpb25AdjExLjAuMFwiLFxuICAgICAgICAgIC8vIG9ubHkgcnVuIHRoaXMgc3RlcCBpZiB3ZSBoYXZlIGZvdW5kIG1hdGNoaW5nIGxhYmVscyBpbiB0aGUgcHJldmlvdXMgc3RlcFxuICAgICAgICAgIC8vIHRoaXMgaXMgdG8gcHJldmVudCB3b3JrZmxvdyBmYWlsdXJlcyBiZWNhdXNlIHRoZSBhY3Rpb24gZmFpbHMgd2hlbiBwcmUtY29uZGl0aW9ucyBhcmUgbm90IG1ldFxuICAgICAgICAgIC8vIGFuZCBjYXVzZXMgYW55IFBSIHRvIGJlIG1hcmtlZCB3aXRoIGEgcmVkIFgsIGxlYWRpbmcgdG8gZXJyb3IgYmxpbmRuZXNzLlxuICAgICAgICAgIGlmOiBgZnJvbUpTT04oc3RlcHMuJHtjaGVja1N0ZXB9Lm91dHB1dHMuJHtjaGVja091dHB1dH0pID4gMGAsXG4gICAgICAgICAgd2l0aDoge1xuICAgICAgICAgICAgZ2l0aHViX3Rva2VuOiBjcmVkZW50aWFscy50b2tlblJlZixcbiAgICAgICAgICAgIGF1dG9fYmFja3BvcnRfbGFiZWxfcHJlZml4OiBsYWJlbFByZWZpeCxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9KTtcbiAgfVxufVxuIl19