Skip to content

Commit

Permalink
feat: add dependency proxy variables
Browse files Browse the repository at this point in the history
  • Loading branch information
ANGkeith committed Oct 4, 2024
1 parent 1e30dd2 commit 9e7b160
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 2 deletions.
11 changes: 11 additions & 0 deletions src/job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,17 @@ export class Job {
this.refreshLongRunningSilentTimeout(writeStreams);

if (imageName && !this._containerId) {
const CI_DEPENDENCY_PROXY_SERVER = this._variables["CI_DEPENDENCY_PROXY_SERVER"];
if (imageName.startsWith(CI_DEPENDENCY_PROXY_SERVER)) {
try {
await Utils.spawn([this.argv.containerExecutable, "login", CI_DEPENDENCY_PROXY_SERVER], cwd);
} catch (e: any) {
assert(!e.stderr.includes("Cannot perform an interactive login"),
`Please authenticate to the Dependency Proxy (${CI_DEPENDENCY_PROXY_SERVER}) https://docs.gitlab.com/ee/user/packages/dependency_proxy/#authenticate-with-the-dependency-proxy`
);
throw e;
}
}
await this.pullImage(writeStreams, imageName);

let dockerCmd = `${this.argv.containerExecutable} create --interactive ${this.generateInjectSSHAgentOptions()} `;
Expand Down
14 changes: 12 additions & 2 deletions src/predefined-variables.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import camelCase from "camelcase";
import {GitData} from "./git-data";
import {Utils} from "./utils";

type PredefinedVariablesOpts = {
gitData: GitData;
argv: {unsetVariables: string[]};
};

export function init ({gitData, argv}: PredefinedVariablesOpts): {[name: string]: string} {
const CI_SERVER_URL = `https://${gitData.remote.host}:443`;
const CI_PROJECT_ROOT_NAMESPACE = gitData.remote.group.split("/")[0];
const CI_PROJECT_NAMESPACE = gitData.remote.group;
const CI_DEPENDENCY_PROXY_SERVER = Utils.removePrefix(CI_SERVER_URL, "https://");
const predefinedVariables: {[key: string]: string} = {
CI: "true",
GITLAB_USER_LOGIN: gitData.user["GITLAB_USER_LOGIN"],
Expand All @@ -16,10 +21,11 @@ export function init ({gitData, argv}: PredefinedVariablesOpts): {[name: string]
CI_COMMIT_SHORT_SHA: gitData.commit.SHA.slice(0, 8), // Changes
CI_COMMIT_SHA: gitData.commit.SHA,
CI_PROJECT_NAME: gitData.remote.project,
CI_PROJECT_ROOT_NAMESPACE: CI_PROJECT_ROOT_NAMESPACE,
CI_PROJECT_TITLE: `${camelCase(gitData.remote.project)}`,
CI_PROJECT_PATH: `${gitData.remote.group}/${gitData.remote.project}`,
CI_PROJECT_PATH_SLUG: `${gitData.remote.group.replace(/\//g, "-")}-${gitData.remote.project}`.toLowerCase(),
CI_PROJECT_NAMESPACE: `${gitData.remote.group}`,
CI_PROJECT_NAMESPACE: CI_PROJECT_NAMESPACE,
CI_PROJECT_VISIBILITY: "internal",
CI_PROJECT_ID: "1217",
CI_COMMIT_REF_PROTECTED: "false",
Expand All @@ -37,12 +43,16 @@ export function init ({gitData, argv}: PredefinedVariablesOpts): {[name: string]
CI_SERVER_FQDN: `${gitData.remote.host}`,
CI_SERVER_HOST: `${gitData.remote.host}`,
CI_SERVER_PORT: `${gitData.remote.port}`,
CI_SERVER_URL: `https://${gitData.remote.host}:443`,
CI_SERVER_URL: CI_SERVER_URL,
CI_SERVER_PROTOCOL: "https",
CI_API_V4_URL: `https://${gitData.remote.host}/api/v4`,
CI_PROJECT_URL: `https://${gitData.remote.host}/${gitData.remote.group}/${gitData.remote.project}`,
CI_TEMPLATE_REGISTRY_HOST: "registry.gitlab.com",
GITLAB_CI: "false",

CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX: `${CI_DEPENDENCY_PROXY_SERVER}/${CI_PROJECT_ROOT_NAMESPACE}/dependency_proxy/containers`,
CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX: `${CI_DEPENDENCY_PROXY_SERVER}/${CI_PROJECT_NAMESPACE}/dependency_proxy/containers`,
CI_DEPENDENCY_PROXY_SERVER: CI_DEPENDENCY_PROXY_SERVER,
};

// Delete variables the user intentionally wants unset
Expand Down
3 changes: 3 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ type ExpandWith = {
};

export class Utils {
static removePrefix = (value: string, prefix: string) =>
value.startsWith(prefix) ? value.slice(prefix.length) : value;

static bash (shellScript: string, cwd = process.cwd()): Promise<{stdout: string; stderr: string; exitCode: number}> {
return execa(shellScript, {shell: "bash", cwd});
}
Expand Down
4 changes: 4 additions & 0 deletions tests/test-cases/dependency-proxy/.gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
job:
image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/busybox:latest
script:
- echo 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import {WriteStreamsMock} from "../../../src/write-streams";
import {handler} from "../../../src/handler";
// import chalk from "chalk";
import {initSpawnSpy, initSpawnSpyReject} from "../../mocks/utils.mock";

Check failure on line 4 in tests/test-cases/dependency-proxy/integration.dependency-proxy.test.ts

View workflow job for this annotation

GitHub Actions / eslint

'initSpawnSpyReject' is defined but never used
import {WhenStatics} from "../../mocks/when-statics";
import {cleanupJobResources, Job} from "../../../src/job";
import {Utils} from "../../../src/utils";

Check failure on line 7 in tests/test-cases/dependency-proxy/integration.dependency-proxy.test.ts

View workflow job for this annotation

GitHub Actions / eslint

'Utils' is defined but never used
import {type} from "os";

Check failure on line 8 in tests/test-cases/dependency-proxy/integration.dependency-proxy.test.ts

View workflow job for this annotation

GitHub Actions / eslint

'type' is defined but never used

let jobs: Job[] = [];

beforeEach(() => {
jobs = [];
initSpawnSpy(WhenStatics.all);
});

afterEach(async () => {
await cleanupJobResources(jobs);
});

describe("dependency-proxy", () => {
test("dependency proxy server not authenticated", async () => {
try {
const writeStreams = new WriteStreamsMock();
// const ciDependencyProxyServerNotAuthenticated = {
// cmdArgs: "docker login gitlab.com:443".split(" "),
// rejection: {
// stderr: "Error: Cannot perform an interactive login from a non TTY device",
// },
// };
// initSpawnSpyReject([ciDependencyProxyServerNotAuthenticated]);

await handler({
cwd: "tests/test-cases/dependency-proxy",
}, writeStreams, jobs);

} catch (e: any) {
expect(e.message).toEqual("Please authenticate to the Dependency Proxy (gitlab.com:443) https://docs.gitlab.com/ee/user/packages/dependency_proxy/#authenticate-with-the-dependency-proxy");
return;
}
throw new Error("Error is expected but not thrown/caught");
});

test("should attempt to pull the correct image", async () => {
const writeStreams = new WriteStreamsMock();

const ciDependencyProxyServerAuthenticated = {
cmdArgs: "docker login gitlab.com:443".split(" "),
returnValue: "Login Succeeded",
};
initSpawnSpy([ciDependencyProxyServerAuthenticated]);

try {
await handler({
cwd: "tests/test-cases/dependency-proxy",
}, writeStreams, jobs);
} catch (e: any) {
// In ci environment, gitlab.com:443 is not authenticated, but at least this shows that we're pulling from the correct path
expect(e.shortMessage).toEqual("Command failed with exit code 1: docker pull gitlab.com:443/gcl/dependency_proxy/containers/busybox:latest");
return;
}
throw new Error("Error is expected but not thrown/caught");

});

});

0 comments on commit 9e7b160

Please sign in to comment.