Skip to content

Commit 7156093

Browse files
Merge pull request #1497 from axodotdev/use-checksum-in-installers
Verify checksums in `install.sh`
2 parents f1b4789 + 34ce732 commit 7156093

67 files changed

Lines changed: 4323 additions & 239 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

cargo-dist-schema/src/lib.rs

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,12 @@ pub type LocalPath = String;
9393
///
9494
/// (Should we normalize this one?)
9595
pub type RelPath = String;
96-
/// The unique ID of an Artifact
97-
pub type ArtifactId = String;
96+
97+
declare_strongly_typed_string! {
98+
/// The unique ID of an Artifact
99+
pub struct ArtifactId => &ArtifactIdRef;
100+
}
101+
98102
/// The unique ID of a System
99103
pub type SystemId = String;
100104
/// The unique ID of an Asset
@@ -403,6 +407,19 @@ pub struct Release {
403407
pub hosting: Hosting,
404408
}
405409

410+
declare_strongly_typed_string! {
411+
/// A lowercase descriptor for a checksum algorithm, like "sha256"
412+
/// or "blake2b".
413+
///
414+
/// TODO(amos): Honestly this type should not exist, it's just what
415+
/// `ChecksumStyle` serializes to. `ChecksumsStyle` should just
416+
/// be serializable, that's it.
417+
pub struct ChecksumExtension => &ChecksumExtensionRef;
418+
419+
/// A checksum value, usually the lower-cased hex string of the checksum
420+
pub struct ChecksumValue => &ChecksumValueRef;
421+
}
422+
406423
/// A distributable artifact that's part of a Release
407424
///
408425
/// i.e. a zip or installer
@@ -415,7 +432,7 @@ pub struct Artifact {
415432
/// indicate you can install the application with `cargo install` or `npm install`.
416433
#[serde(skip_serializing_if = "Option::is_none")]
417434
#[serde(default)]
418-
pub name: Option<String>,
435+
pub name: Option<ArtifactId>,
419436
/// The kind of artifact this is (e.g. "executable-zip")
420437
#[serde(flatten)]
421438
pub kind: ArtifactKind,
@@ -442,14 +459,14 @@ pub struct Artifact {
442459
/// id of an Artifact that contains the checksum for this Artifact
443460
#[serde(skip_serializing_if = "Option::is_none")]
444461
#[serde(default)]
445-
pub checksum: Option<String>,
462+
pub checksum: Option<ArtifactId>,
446463
/// checksums for this artifact
447464
///
448465
/// keys are the name of an algorithm like "sha256" or "sha512"
449466
/// values are the actual hex string of the checksum
450467
#[serde(default)]
451468
#[serde(skip_serializing_if = "BTreeMap::is_empty")]
452-
pub checksums: BTreeMap<String, String>,
469+
pub checksums: BTreeMap<ChecksumExtension, ChecksumValue>,
453470
}
454471

455472
/// An asset contained in an artifact (executable, license, etc.)
@@ -546,7 +563,7 @@ pub struct ExecutableAsset {
546563
/// The name of the Artifact containing symbols for this executable
547564
#[serde(skip_serializing_if = "Option::is_none")]
548565
#[serde(default)]
549-
pub symbols_artifact: Option<String>,
566+
pub symbols_artifact: Option<ArtifactId>,
550567
}
551568

552569
/// A C dynamic library artifact (so/dylib/dll)
@@ -555,7 +572,7 @@ pub struct DynamicLibraryAsset {
555572
/// The name of the Artifact containing symbols for this library
556573
#[serde(skip_serializing_if = "Option::is_none")]
557574
#[serde(default)]
558-
pub symbols_artifact: Option<String>,
575+
pub symbols_artifact: Option<ArtifactId>,
559576
}
560577

561578
/// A C static library artifact (a/lib)
@@ -564,7 +581,7 @@ pub struct StaticLibraryAsset {
564581
/// The name of the Artifact containing symbols for this library
565582
#[serde(skip_serializing_if = "Option::is_none")]
566583
#[serde(default)]
567-
pub symbols_artifact: Option<String>,
584+
pub symbols_artifact: Option<ArtifactId>,
568585
}
569586

570587
/// Info about a manifest version
@@ -612,7 +629,7 @@ impl Format {
612629

613630
impl DistManifest {
614631
/// Create a new DistManifest
615-
pub fn new(releases: Vec<Release>, artifacts: BTreeMap<String, Artifact>) -> Self {
632+
pub fn new(releases: Vec<Release>, artifacts: BTreeMap<ArtifactId, Artifact>) -> Self {
616633
Self {
617634
dist_version: None,
618635
announcement_tag: None,
@@ -655,7 +672,7 @@ impl DistManifest {
655672
pub fn artifacts_for_release<'a>(
656673
&'a self,
657674
release: &'a Release,
658-
) -> impl Iterator<Item = (&'a str, &'a Artifact)> {
675+
) -> impl Iterator<Item = (&'a ArtifactIdRef, &'a Artifact)> {
659676
release
660677
.artifacts
661678
.iter()

cargo-dist/src/backend/installer/homebrew.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Code for generating formula.rb
22
33
use axoasset::LocalAsset;
4-
use cargo_dist_schema::DistManifest;
4+
use cargo_dist_schema::{ChecksumValue, DistManifest};
55
use serde::Serialize;
66
use spdx::{
77
expression::{ExprNode, Operator},
@@ -119,7 +119,7 @@ struct HomebrewFragment {
119119
/// SHA256 sum of the fragment. When building "just the installers", like
120120
/// when running `dist build --artifacts global` locally, we don't have
121121
/// the SHA256 for the fragment, since we didn't actually build them.
122-
sha256: Option<String>,
122+
sha256: Option<ChecksumValue>,
123123

124124
/// homebrew package dependencies
125125
dependencies: Vec<String>,

cargo-dist/src/backend/installer/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use std::collections::BTreeMap;
66

77
use camino::Utf8PathBuf;
8-
use cargo_dist_schema::{EnvironmentVariables, Hosting, TargetTriple};
8+
use cargo_dist_schema::{ArtifactId, EnvironmentVariables, Hosting, TargetTriple};
99
use homebrew::HomebrewFragments;
1010
use macpkg::PkgInstallerInfo;
1111
use serde::Serialize;
@@ -99,7 +99,7 @@ pub struct InstallerInfo {
9999
#[derive(Debug, Clone, Serialize)]
100100
pub struct ExecutableZipFragment {
101101
/// The id of the artifact
102-
pub id: String,
102+
pub id: ArtifactId,
103103
/// The target the artifact supports
104104
pub target_triple: TargetTriple,
105105
/// The executables the artifact contains (name, assumed at root)
@@ -120,7 +120,7 @@ pub struct ExecutableZipFragment {
120120
#[derive(Debug, Clone, Serialize)]
121121
pub struct UpdaterFragment {
122122
/// The id of the artifact
123-
pub id: String,
123+
pub id: ArtifactId,
124124
/// The binary the artifact contains (name, assumed at root)
125-
pub binary: String,
125+
pub binary: ArtifactId,
126126
}

cargo-dist/src/backend/installer/npm.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use axoasset::{LocalAsset, SourceFile};
44
use camino::{Utf8Path, Utf8PathBuf};
5-
use cargo_dist_schema::{GlibcVersion, TargetTriple};
5+
use cargo_dist_schema::{ArtifactId, GlibcVersion, TargetTriple};
66
use serde::Serialize;
77

88
use super::InstallerInfo;
@@ -46,7 +46,7 @@ type PackageJsonPlatforms = SortedMap<TargetTriple, PackageJsonPlatform>;
4646
#[derive(Debug, Clone, Serialize)]
4747
#[serde(rename_all = "camelCase")]
4848
struct PackageJsonPlatform {
49-
artifact_name: String,
49+
artifact_name: ArtifactId,
5050
bins: SortedMap<String, String>,
5151
zip_ext: String,
5252
}

cargo-dist/src/backend/installer/shell.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,27 @@
11
//! Code for generating installer.sh
22
33
use axoasset::LocalAsset;
4+
use cargo_dist_schema::DistManifest;
45

56
use crate::{backend::templates::TEMPLATE_INSTALLER_SH, errors::DistResult, DistGraph};
67

78
use super::InstallerInfo;
89

9-
pub(crate) fn write_install_sh_script(dist: &DistGraph, info: &InstallerInfo) -> DistResult<()> {
10+
pub(crate) fn write_install_sh_script(
11+
dist: &DistGraph,
12+
info: &InstallerInfo,
13+
manifest: &DistManifest,
14+
) -> DistResult<()> {
1015
let mut info = info.clone();
11-
info.platform_support = Some(dist.release(info.release).platform_support.clone());
16+
let platform_support = dist.release(info.release).platform_support.clone();
17+
18+
info.platform_support = Some(if dist.local_builds_are_lies {
19+
// if local builds are lies, the artifacts that are "fake-built" have a different
20+
// checksum every time, so we can't use those in the generated installer
21+
platform_support
22+
} else {
23+
platform_support.with_checksums_from_manifest(manifest)
24+
});
1225

1326
let script = dist
1427
.templates

cargo-dist/src/config/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::collections::BTreeMap;
55
use axoasset::{toml_edit, SourceFile};
66
use axoproject::local_repo::LocalRepo;
77
use camino::{Utf8Path, Utf8PathBuf};
8-
use cargo_dist_schema::{TargetTriple, TargetTripleRef};
8+
use cargo_dist_schema::{ChecksumExtensionRef, TargetTriple, TargetTripleRef};
99
use serde::{Deserialize, Serialize};
1010

1111
use crate::announce::TagSettings;
@@ -662,16 +662,16 @@ pub enum ChecksumStyle {
662662

663663
impl ChecksumStyle {
664664
/// Get the extension of a checksum
665-
pub fn ext(self) -> &'static str {
666-
match self {
665+
pub fn ext(self) -> &'static ChecksumExtensionRef {
666+
ChecksumExtensionRef::from_str(match self {
667667
ChecksumStyle::Sha256 => "sha256",
668668
ChecksumStyle::Sha512 => "sha512",
669669
ChecksumStyle::Sha3_256 => "sha3-256",
670670
ChecksumStyle::Sha3_512 => "sha3-512",
671671
ChecksumStyle::Blake2s => "blake2s",
672672
ChecksumStyle::Blake2b => "blake2b",
673673
ChecksumStyle::False => "false",
674-
}
674+
})
675675
}
676676
}
677677

cargo-dist/src/errors.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
use axoproject::errors::AxoprojectError;
1010
use backtrace::Backtrace;
1111
use camino::Utf8PathBuf;
12-
use cargo_dist_schema::TargetTriple;
12+
use cargo_dist_schema::{ArtifactId, TargetTriple};
1313
use color_backtrace::BacktracePrinter;
1414
use console::style;
1515
use miette::{Diagnostic, SourceOffset, SourceSpan};
@@ -264,7 +264,7 @@ pub enum DistError {
264264
#[diagnostic(help("depends on {spec1} and {spec2}"))]
265265
MultiPackage {
266266
/// Name of the artifact
267-
artifact_name: String,
267+
artifact_name: ArtifactId,
268268
/// One of the packages
269269
spec1: String,
270270
/// A different package
@@ -276,7 +276,7 @@ pub enum DistError {
276276
#[diagnostic(help("This should be impossible, you did nothing wrong, please file an issue!"))]
277277
NoPackage {
278278
/// Name of the msi
279-
artifact_name: String,
279+
artifact_name: ArtifactId,
280280
},
281281

282282
/// These GUIDs for msi's are required and enforced by `dist generate --check`

cargo-dist/src/host.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::{
1414
DistError, DistGraph, DistGraphBuilder, HostingInfo,
1515
};
1616
use axoproject::WorkspaceGraph;
17-
use cargo_dist_schema::{DistManifest, Hosting};
17+
use cargo_dist_schema::{ArtifactIdRef, DistManifest, Hosting};
1818
use gazenot::{AnnouncementKey, Gazenot};
1919

2020
/// Do hosting
@@ -212,6 +212,8 @@ fn check_hosting(_dist: &DistGraph, _manifest: &DistManifest, _abyss: &Gazenot)
212212
}
213213

214214
fn upload_to_hosting(dist: &DistGraph, manifest: &DistManifest, abyss: &Gazenot) -> DistResult<()> {
215+
const DIST_MANIFEST_ARTIFACT_ID: &ArtifactIdRef = ArtifactIdRef::from_str("dist-manifest.json");
216+
215217
// Gather up the files to upload for each release
216218
let files = manifest.releases.iter().filter_map(|release| {
217219
// Github Releases only has semantics on Announce
@@ -224,8 +226,8 @@ fn upload_to_hosting(dist: &DistGraph, manifest: &DistManifest, abyss: &Gazenot)
224226
let files = manifest
225227
.artifacts_for_release(release)
226228
.filter_map(|(_id, artifact)| artifact.name.as_deref())
227-
.chain(Some("dist-manifest.json"))
228-
.map(|name| dist.dist_dir.join(name))
229+
.chain(Some(DIST_MANIFEST_ARTIFACT_ID))
230+
.map(|name| dist.dist_dir.join(name.as_str()))
229231
.collect::<Vec<_>>();
230232
Some((set, files))
231233
} else {

cargo-dist/src/init.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1032,7 +1032,7 @@ fn apply_dist_to_metadata(metadata: &mut toml_edit::Item, meta: &DistMetadata) {
10321032
table,
10331033
"checksum",
10341034
"# Checksums to generate for each App\n",
1035-
checksum.map(|c| c.ext()),
1035+
checksum.map(|c| c.ext().as_str()),
10361036
);
10371037

10381038
apply_optional_value(

0 commit comments

Comments
 (0)