diff --git a/action.yaml b/action.yaml index 123833a..e1c1691 100644 --- a/action.yaml +++ b/action.yaml @@ -75,6 +75,9 @@ inputs: description: Whether to error if a release for the same version has already been uploaded. required: false default: false + include-output-paths: + description: Whether to register the output paths of each flake output with FlakeHub. + required: false flakehub-push-binary: description: Run a version of the `flakehub-push` binary from somewhere already on disk. Conflicts with all other `flakehub-push-*` options. @@ -119,6 +122,7 @@ runs: FLAKEHUB_PUSH_EXTRA_TAGS: ${{ inputs.extra-tags }} FLAKEHUB_PUSH_SPDX_EXPRESSION: ${{ inputs.spdx-expression }} FLAKEHUB_PUSH_ERROR_ON_CONFLICT: ${{ inputs.error-on-conflict }} + FLAKEHUB_PUSH_INCLUDE_OUTPUT_PATHS: ${{ inputs.include-output-paths }} # Also GITHUB_REPOSITORY, GITHUB_REF_NAME, GITHUB_TOKEN, ACTIONS_ID_TOKEN_REQUEST_TOKEN, ACTIONS_ID_TOKEN_REQUEST_URL run: | if [ "${RUNNER_OS}" == "Linux" ]; then diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 76be525..1f0a54e 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -101,6 +101,9 @@ pub(crate) struct FlakeHubPushCli { #[clap(flatten)] pub instrumentation: instrumentation::Instrumentation, + + #[clap(long, env = "FLAKEHUB_PUSH_INCLUDE_OUTPUT_PATHS", value_parser = EmptyBoolParser, default_value_t = false)] + pub(crate) include_output_paths: bool, } #[derive(Clone, Debug)] @@ -275,6 +278,7 @@ impl FlakeHubPushCli { spdx_expression, extra_tags, error_on_conflict, + include_output_paths, } = self; let mut extra_labels: Vec<_> = extra_labels.into_iter().filter(|v| !v.is_empty()).collect(); @@ -457,6 +461,7 @@ impl FlakeHubPushCli { extra_labels, spdx_expression.0, error_on_conflict, + include_output_paths, ) .await?; @@ -493,6 +498,7 @@ async fn push_new_release( extra_labels: Vec, spdx_expression: Option, error_if_release_conflicts: bool, + include_output_paths: bool, ) -> color_eyre::Result<()> { let span = tracing::Span::current(); span.record("upload_name", tracing::field::display(upload_name.clone())); @@ -552,7 +558,7 @@ async fn push_new_release( .pointer("/resolved/dir") .and_then(serde_json::Value::as_str); - let flake_outputs = get_flake_outputs(flake_locked_url).await?; + let flake_outputs = get_flake_outputs(flake_locked_url, include_output_paths).await?; tracing::debug!("Got flake outputs: {:?}", flake_outputs); let source = match flake_metadata_value_resolved_dir { diff --git a/src/flake_info.rs b/src/flake_info.rs index a36729a..bcaf3be 100644 --- a/src/flake_info.rs +++ b/src/flake_info.rs @@ -132,16 +132,28 @@ pub(crate) async fn get_flake_metadata(directory: &Path) -> color_eyre::Result color_eyre::Result { +pub(crate) async fn get_flake_outputs( + flake_url: &str, + include_output_paths: bool, +) -> color_eyre::Result { let tempdir = tempfile::Builder::new() .prefix("flakehub_push_outputs") .tempdir() .wrap_err("Creating tempdir")?; - let flake_contents = include_str!("mixed-flake.nix").replace( - FLAKE_URL_PLACEHOLDER_UUID, - &flake_url.escape_default().to_string(), - ); + let flake_contents = include_str!("mixed-flake.nix") + .replace( + FLAKE_URL_PLACEHOLDER_UUID, + &flake_url.escape_default().to_string(), + ) + .replace( + "INCLUDE_OUTPUT_PATHS", + if include_output_paths { + "true" + } else { + "false" + }, + ); let mut flake = tokio::fs::File::create(tempdir.path().join("flake.nix")).await?; flake.write_all(flake_contents.as_bytes()).await?; diff --git a/src/mixed-flake.nix b/src/mixed-flake.nix index b46bfda..9c3ca73 100644 --- a/src/mixed-flake.nix +++ b/src/mixed-flake.nix @@ -2,6 +2,8 @@ inputs.flake.url = "c9026fc0-ced9-48e0-aa3c-fc86c4c86df1"; outputs = inputs: { + includeOutputPaths = INCLUDE_OUTPUT_PATHS; + contents = let getFlakeOutputs = flake: @@ -69,7 +71,33 @@ shortDescription = attrs.shortDescription or null; what = attrs.what or null; #evalChecks = attrs.evalChecks or {}; - } + } // ( + if inputs.self.includeOutputPaths then + { + derivation = + if attrs ? derivation + then builtins.unsafeDiscardStringContext attrs.derivation.drvPath + else null; + outputs = + if attrs ? derivation + then + builtins.listToAttrs + ( + builtins.map + (outputName: + { + name = outputName; + value = attrs.derivation.${outputName}.outPath; + } + ) + attrs.derivation.outputs + ) + else + null; + } + else + { } + ) else { }; in