Skip to content

Commit

Permalink
[nixpacks] add publish function
Browse files Browse the repository at this point in the history
  • Loading branch information
tsirysndr committed Mar 11, 2024
1 parent 9cae50a commit 59b10e0
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 8 deletions.
2 changes: 1 addition & 1 deletion nixpacks/deno.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@daggerverse/nixpacks",
"version": "0.1.0",
"version": "0.1.1",
"exports": "./mod.ts",
"importMap": "import_map.json",
"tasks": {
Expand Down
2 changes: 1 addition & 1 deletion nixpacks/src/dagger/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { build, plan, dev } from "./jobs.ts";
export { build, plan, publish, dev } from "./jobs.ts";
59 changes: 54 additions & 5 deletions nixpacks/src/dagger/jobs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
* @module nixpacks
* @description This module provides a set of functions to build an OCI image from your project using nixpacks.
*/
import { Secret } from "../../deps.ts";
import { dag, Directory, Container, File } from "../../deps.ts";
import { docker } from "./lib.ts";
import { docker, getRegistryPassword } from "./lib.ts";
import { getDirectory } from "./lib.ts";

export enum Job {
build = "build",
plan = "plan",
dev = "dev",
publish = "publish",
}

export const exclude = [];
Expand All @@ -20,7 +22,7 @@ export const exclude = [];
* @function
* @description Build an OCI image from your project using nixpacks
* @param {string | Directory | undefined} src
* @returns {string}
* @returns {Promise<string>}
*/
export async function build(
src: string | Directory,
Expand Down Expand Up @@ -57,7 +59,7 @@ export async function build(
* @function
* @description Generate a plan for building an OCI image from your project using nixpacks
* @param {string | Directory | undefined} src
* @returns {string}
* @returns {Promise<File |string>}
*/
export async function plan(
src: string | Directory,
Expand Down Expand Up @@ -90,7 +92,7 @@ export async function plan(
* @function
* @description Return a Container with nixpacks installed
* @param {string | Directory | undefined} src
* @returns {string}
* @returns {Promise<string>}
*/
export async function dev(
src: string | Directory | undefined = "."
Expand Down Expand Up @@ -120,24 +122,71 @@ export async function dev(
return ctr.id();
}

/**
* Publish an OCI image to a registry
*
* @function
* @description Publish an OCI image to a registry
* @param {string} username
* @param {string | Secret} password
* @param {string} ref
* @param {string | undefined} registry
* @returns {Promise<string>}
*/
export async function publish(
username: string,
password: string | Secret,
ref: string,
registry: string | undefined = "docker.io"
): Promise<string> {
const secret = await getRegistryPassword(password);
const ctr = dag
.pipeline(Job.publish)
.container()
.from("pkgxdev/pkgx:latest")
.withExec(["apt-get", "update"])
.withExec(["apt-get", "install", "-y", "ca-certificates"])
.withMountedCache("/root/.pkgx", dag.cacheVolume("pkgx-cache"))
.withExec(["pkgx", "install", "docker"])
.withExec(["docker", "-v"])
.withServiceBinding("dockerd", docker("25.0.3", true))
.withEnvVariable("DOCKER_HOST", "tcp://dockerd:2375")
.withSecretVariable("REGISTRY_PASSWORD", secret!)
.withExec([
"bash",
"-c",
`echo $REGISTRY_PASSWORD | docker login ${registry} -u ${username} --password-stdin`,
])
.withExec(["docker", "push", ref]);
return ctr.stdout();
}

export type JobExec =
| ((src: string | Directory, name: string, path?: string) => Promise<string>)
| ((
src: string | Directory,
path?: string,
format?: string
) => Promise<File | string>)
| ((src?: string) => Promise<Container | string>);
| ((src?: string) => Promise<Container | string>)
| ((
username: string,
password: string | Secret,
ref: string,
registry: string | undefined
) => Promise<string>);

export const runnableJobs: Record<Job, JobExec> = {
[Job.build]: build,
[Job.plan]: plan,
[Job.publish]: publish,
[Job.dev]: dev,
};

export const jobDescriptions: Record<Job, string> = {
[Job.build]: "Build an OCI image from your project using nixpacks",
[Job.plan]:
"Generate a plan for building an OCI image from your project using nixpacks",
[Job.publish]: "Publish an OCI image to a registry",
[Job.dev]: "Return a Container with nixpacks installed",
};
31 changes: 30 additions & 1 deletion nixpacks/src/dagger/lib.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { dag, Directory, DirectoryID, CacheSharingMode } from "../../deps.ts";
import {
dag,
Directory,
DirectoryID,
Secret,
SecretID,
CacheSharingMode,
} from "../../deps.ts";

export const getDirectory = async (
src: string | Directory | undefined = "."
Expand Down Expand Up @@ -57,3 +64,25 @@ export const docker = (version = "24.0", cached = false) => {
)
.asService();
};

export const getRegistryPassword = async (password: string | Secret) => {
if (Deno.env.get("REGISTRY_PASSWORD")) {
return dag.setSecret(
"REGISTRY_PASSWORD",
Deno.env.get("REGISTRY_PASSWORD")!
);
}
if (password && typeof password === "string") {
try {
const secret = dag.loadSecretFromID(password as SecretID);
await secret.id();
return secret;
} catch (_) {
return dag.setSecret("REGISTRY_PASSWORD", password);
}
}
if (password && password instanceof Secret) {
return password;
}
return undefined;
};

0 comments on commit 59b10e0

Please sign in to comment.