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

fix!: sync .well-known dir by default #3759

Merged
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
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@

The output of `dfx canister status` has been also changed to use consistent capitalization of words.

### fix!(frontend-canister): include `.well-known` directory by default for asset upload

When uploading assets to an asset canister, `dfx` by default excludes directories and files with names that start with `.`.
`dfx` will start including folders with the name `.well-known` by default.
It is possible to override this in `.ic-assets.json` like this:

``` json
{
"match": ".well-known",
"ignore": true
}
```

## Dependencies

### Updated to [agent-rs 0.35.0](https://github.com/dfinity/agent-rs/blob/main/CHANGELOG.md#0350---2024-05-10)
Expand Down
8 changes: 2 additions & 6 deletions e2e/tests-dfx/assetscanister.bash
Original file line number Diff line number Diff line change
Expand Up @@ -1217,7 +1217,7 @@ EOF
dfx_start

touch src/e2e_project_frontend/assets/thing.json
touch src/e2e_project_frontend/assets/.ignored-by-defualt.txt
touch src/e2e_project_frontend/assets/.ignored-by-default.txt

mkdir src/e2e_project_frontend/assets/.well-known
touch src/e2e_project_frontend/assets/.well-known/thing.json
Expand All @@ -1229,10 +1229,6 @@ EOF
touch src/e2e_project_frontend/assets/.well-known/.another-hidden/ignored.txt

echo '[
{
"match": ".well-known",
"ignore": false
},
{
"match": "**/*",
"cache": { "max_age": 2000 }
Expand Down Expand Up @@ -1274,7 +1270,7 @@ EOF
assert_match "cache-control: max-age=2000"
assert_match "x-header: x-value"

assert_command curl -vv "http://localhost:$PORT/.ignored-by-defualt.txt?canisterId=$ID"
assert_command curl -vv "http://localhost:$PORT/.ignored-by-default.txt?canisterId=$ID"
assert_match "404 Not Found"
assert_command curl -vv "http://localhost:$PORT/.well-known/.hidden/ignored.txt?canisterId=$ID"
assert_match "404 Not Found"
Expand Down
75 changes: 66 additions & 9 deletions src/canisters/frontend/ic-asset/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ use std::collections::HashMap;
use std::path::Path;
use walkdir::WalkDir;

const KNOWN_DIRECTORIES: [&str; 1] = [".well-known"];

/// Sets the contents of the asset canister to the contents of a directory, including deleting old assets.
pub async fn upload_content_and_assemble_sync_operations(
canister: &Canister<'_>,
Expand Down Expand Up @@ -214,15 +216,17 @@ fn sort_batch_operations(mut args: CommitBatchArguments) -> CommitBatchArguments
}

fn include_entry(entry: &walkdir::DirEntry, config: &AssetConfig) -> bool {
let starts_with_a_dot = entry
.file_name()
.to_str()
.map(|s| s.starts_with('.'))
.unwrap_or(false);

match (starts_with_a_dot, config.ignore) {
(dot, None) => !dot,
(_dot, Some(ignored)) => !ignored,
if let Some(ignored) = config.ignore {
!ignored
} else if let Some(entry_name) = entry.file_name().to_str() {
let is_known = if entry.path().is_dir() {
KNOWN_DIRECTORIES.contains(&entry_name)
} else {
false
};
is_known || !entry_name.starts_with('.')
} else {
true
}
}

Expand Down Expand Up @@ -778,6 +782,59 @@ mod test_gathering_asset_descriptors_with_tempdir {
assert_eq!(asset_descriptors, expected_asset_descriptors);
}

#[test]
fn known_directories_included_by_default() {
let files = HashMap::from([
// a typical use case of the .well-known folder
(
Path::new(".well-known/ic-domains").to_path_buf(),
"foo.bar.com".to_string(),
),
]);

let assets_temp_dir = create_temporary_assets_directory(files);
let assets_dir = assets_temp_dir.path().canonicalize().unwrap();
let mut asset_descriptors = dbg!(gather_asset_descriptors(&[&assets_dir]));

let mut expected_asset_descriptors = vec![
AssetDescriptor::default_from_path(&assets_dir, "file"),
AssetDescriptor::default_from_path(&assets_dir, ".well-known/ic-domains"),
];

expected_asset_descriptors.sort_by_key(|v| v.source.clone());
asset_descriptors.sort_by_key(|v| v.source.clone());
assert_eq!(asset_descriptors, expected_asset_descriptors);
}

#[test]
fn known_directories_can_be_ignored() {
let files = HashMap::from([
// a typical use case of the .well-known folder
(
Path::new(".well-known/ic-domains").to_path_buf(),
"foo.bar.com".to_string(),
),
(
Path::new(".ic-assets.json").to_path_buf(),
r#"[
{"match": ".well-known", "ignore": true}
]"#
.to_string(),
),
]);

let assets_temp_dir = create_temporary_assets_directory(files);
let assets_dir = assets_temp_dir.path().canonicalize().unwrap();
let mut asset_descriptors = dbg!(gather_asset_descriptors(&[&assets_dir]));

let mut expected_asset_descriptors =
vec![AssetDescriptor::default_from_path(&assets_dir, "file")];

expected_asset_descriptors.sort_by_key(|v| v.source.clone());
asset_descriptors.sort_by_key(|v| v.source.clone());
assert_eq!(asset_descriptors, expected_asset_descriptors);
}

#[test]
fn bonanza() {
let files = HashMap::from([
Expand Down