Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use latest Deno 2 version #1243

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/pages/docs/providers/deno.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Deno is detected if there is a `deno.{json,jsonc}` file found or if any `.{ts,ts

Apps built with [Deno Fresh](https://fresh.deno.dev/) should work out of the box.

Deno 1 will be installed if the `NIXPACKS_USE_DENO_1` environment variable is truthy or `engines.deno` is set to some variant of `1` (e.g. `1`, `v1`, `^1.0`) in either `package.json` or `deno.json`; otherwise, Deno 2 will be used.

## Install

_None_
Expand Down
5 changes: 5 additions & 0 deletions examples/deno1/deno.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"engines": {
"deno": "1"
}
}
7 changes: 7 additions & 0 deletions examples/deno1/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as o from "https://deno.land/x/cowsay/mod.ts";

let m = o.say({
text: "Hello from Deno",
});

console.log(m);
3 changes: 3 additions & 0 deletions src/nixpacks/nix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ pub const NIXPKGS_ARCHIVE: &str = "5148520bfab61f99fd25fb9ff7bfbb50dad3c9db";
// Version of the Nix archive that uses OpenSSL 1.1
pub const NIXPACKS_ARCHIVE_LEGACY_OPENSSL: &str = "a0b7e70db7a55088d3de0cc370a59f9fbcc906c3";

// Version of the Nix archive with the latest Deno
pub const NIXPACKS_ARCHIVE_LATEST_DENO: &str = "734af41a2b6a21fb9bf70d9f170563b6932364bb";

/// Contains all the data needed to generate a Nix expression file for installing Nix dependencies.
#[derive(Eq, PartialEq, Default, Debug, Clone)]
struct NixGroup {
Expand Down
5 changes: 4 additions & 1 deletion src/nixpacks/plan/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,10 @@ impl NixpacksBuildPlanGenerator<'_> {
plan.add_variables(Environment::clone_variables(new_env));
}

plan.pin(new_env.is_config_variable_truthy("DEBIAN"));
plan.pin(
new_env.is_config_variable_truthy("DEBIAN"),
plan.pinned_archive.clone(),
);
if plan.clone().phases.unwrap_or_default().is_empty() {
// try again in a subdir
let dir_count = app.paths.clone().iter().filter(|p| p.is_dir()).count();
Expand Down
21 changes: 17 additions & 4 deletions src/nixpacks/plan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ use self::{
phase::{Phase, Phases, StartPhase},
topological_sort::topological_sort,
};
use super::images::{DEBIAN_BASE_IMAGE, UBUNTU_BASE_IMAGE};
use super::{
images::{DEBIAN_BASE_IMAGE, UBUNTU_BASE_IMAGE},
nix::NIXPACKS_ARCHIVE_LEGACY_OPENSSL,
};
use crate::nixpacks::{
app::{App, StaticAssets},
environment::{Environment, EnvironmentVariables},
Expand Down Expand Up @@ -46,6 +49,8 @@ pub struct BuildPlan {

pub phases: Option<Phases>,

pub pinned_archive: Option<String>,

#[serde(rename = "start")]
pub start_phase: Option<StartPhase>,
}
Expand Down Expand Up @@ -292,7 +297,7 @@ impl BuildPlan {
}

/// Store the base image and phase dependencies in this BuildPlan, for later reproducibility.
pub fn pin(&mut self, use_debian: bool) {
pub fn pin(&mut self, use_debian: bool, archive: Option<String>) {
self.providers = Some(Vec::new());
if self.build_image.is_none() {
let base_image = if use_debian {
Expand All @@ -306,12 +311,20 @@ impl BuildPlan {
self.resolve_phase_names();
let phases = self.phases.get_or_insert(Phases::default());
for phase in (*phases).values_mut() {
phase.pin(use_debian);
phase.pin(if archive.is_some() {
archive.clone()
} else if use_debian {
Some(NIXPACKS_ARCHIVE_LEGACY_OPENSSL.to_string())
} else {
None
});
}

if let Some(start) = &mut self.start_phase {
start.pin();
}

self.pinned_archive = archive;
}

/// Prefix each phase name with the name of the provider that generated the phase, in the case of multiple providers.
Expand Down Expand Up @@ -485,7 +498,7 @@ mod test {
)
.unwrap();

plan.pin(false);
plan.pin(false, None);
assert_eq!(
plan.get_phase("setup").unwrap().nix_pkgs,
Some(vec!["nodejs".to_string(), "yarn".to_string()])
Expand Down
8 changes: 4 additions & 4 deletions src/nixpacks/plan/phase.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::nixpacks::{
images::{DEFAULT_BASE_IMAGE, STANDALONE_IMAGE},
nix::{pkg::Pkg, NIXPACKS_ARCHIVE_LEGACY_OPENSSL, NIXPKGS_ARCHIVE},
nix::{pkg::Pkg, NIXPKGS_ARCHIVE},
};
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashSet};
Expand Down Expand Up @@ -209,10 +209,10 @@ impl Phase {
}

/// Store the phase dependencies for later reproducibility.
pub fn pin(&mut self, use_legacy_openssl: bool) {
pub fn pin(&mut self, archive: Option<String>) {
if self.uses_nix() && self.nixpkgs_archive.is_none() {
self.nixpkgs_archive = if use_legacy_openssl {
Some(NIXPACKS_ARCHIVE_LEGACY_OPENSSL.to_string())
self.nixpkgs_archive = if let Some(archive) = archive {
Some(archive)
} else {
Some(NIXPKGS_ARCHIVE.to_string())
}
Expand Down
74 changes: 71 additions & 3 deletions src/providers/deno.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::Provider;
use crate::nixpacks::{
app::App,
environment::Environment,
nix::pkg::Pkg,
nix::{pkg::Pkg, NIXPACKS_ARCHIVE_LATEST_DENO},
plan::{
phase::{Phase, StartPhase},
BuildPlan,
Expand All @@ -20,9 +20,21 @@ pub struct DenoTasks {
pub start: Option<String>,
}

#[derive(Serialize, Deserialize, Default, Debug)]
pub struct DenoEngines {
pub deno: Option<String>,
}

#[derive(Serialize, Deserialize, Default, Debug)]
pub struct DenoJson {
pub tasks: Option<DenoTasks>,
pub engines: Option<DenoEngines>,
}

#[derive(Serialize, Deserialize, Default, Debug)]
pub struct PackageJson {
pub engines: Option<DenoEngines>,
pub scripts: Option<DenoTasks>,
}

pub struct DenoProvider {}
Expand All @@ -42,10 +54,28 @@ impl Provider for DenoProvider {
|| app.find_match(&re, "**/*.{ts,tsx,js,jsx}")?)
}

fn get_build_plan(&self, app: &App, _env: &Environment) -> Result<Option<BuildPlan>> {
fn get_build_plan(&self, app: &App, env: &Environment) -> Result<Option<BuildPlan>> {
let mut plan = BuildPlan::default();

let setup = Phase::setup(Some(vec![Pkg::new("deno")]));
let mut setup = Phase::setup(Some(vec![Pkg::new("deno")]));

let package_json = app.read_json::<PackageJson>("package.json");
let deno_json = app.read_json::<DenoJson>("deno.json");
let v1_regex = Regex::new(r"^((>=)|\^)?v?1")?;
if !(env.is_config_variable_truthy("USE_DENO_1")
|| package_json
.map(|p| p.engines.map(|e| e.deno.map(|d| v1_regex.is_match(&d))))
.unwrap_or(Some(Some(false)))
.unwrap_or(Some(false))
.unwrap_or(false)
|| deno_json
.map(|p| p.engines.map(|e| e.deno.map(|d| v1_regex.is_match(&d))))
.unwrap_or(Some(Some(false)))
.unwrap_or(Some(false))
.unwrap_or(false))
{
setup.pin(Some(NIXPACKS_ARCHIVE_LATEST_DENO.to_string()));
}
plan.add_phase(setup);

if let Some(build_cmd) = DenoProvider::get_build_cmd(app)? {
Expand Down Expand Up @@ -115,3 +145,41 @@ impl DenoProvider {
Ok(Some(relative_path_to_index))
}
}

#[cfg(test)]
mod tests {

use super::*;

#[test]
fn test_deno_versions() {
let deno = DenoProvider {};
assert_eq!(
deno.get_build_plan(&App::new("examples/deno").unwrap(), &Environment::default())
.unwrap()
.unwrap()
.phases
.unwrap()
.get("setup")
.unwrap()
.nixpkgs_archive
.as_ref()
.unwrap(),
&NIXPACKS_ARCHIVE_LATEST_DENO.to_string()
);
assert_eq!(
deno.get_build_plan(
&App::new("examples/deno1").unwrap(),
&Environment::default()
)
.unwrap()
.unwrap()
.phases
.unwrap()
.get("setup")
.unwrap()
.nixpkgs_archive,
None
);
}
}
35 changes: 35 additions & 0 deletions tests/snapshots/generate_plan_tests__deno1.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
source: tests/generate_plan_tests.rs
expression: plan
snapshot_kind: text
---
{
"providers": [],
"buildImage": "[build_image]",
"variables": {
"NIXPACKS_METADATA": "deno"
},
"phases": {
"build": {
"name": "build",
"dependsOn": [
"install",
"setup"
],
"cmds": [
"deno cache src/index.ts"
]
},
"setup": {
"name": "setup",
"nixPkgs": [
"deno"
],
"nixOverlays": [],
"nixpkgsArchive": "[archive]"
}
},
"start": {
"cmd": "deno run --allow-all src/index.ts"
}
}
36 changes: 36 additions & 0 deletions tests/snapshots/generate_plan_tests__deno2.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
source: tests/generate_plan_tests.rs
expression: plan
snapshot_kind: text
---
{
"providers": [],
"buildImage": "[build_image]",
"variables": {
"NIXPACKS_METADATA": "deno",
"NIXPACKS_USE_DENO_2": "1"
},
"phases": {
"build": {
"name": "build",
"dependsOn": [
"install",
"setup"
],
"cmds": [
"deno cache src/index.ts"
]
},
"setup": {
"name": "setup",
"nixPkgs": [
"deno"
],
"nixOverlays": [],
"nixpkgsArchive": "[archive]"
}
},
"start": {
"cmd": "deno run --allow-all src/index.ts"
}
}
Loading