harn-stdlib 0.8.25

Embedded Harn standard library source catalog
Documentation
/** std/gha - GitHub Actions output, summary, and annotation helpers. */
type GhaAnnotationOptions = {
  file?: string,
  line?: int,
  endLine?: int,
  col?: int,
  endColumn?: int,
  title?: string,
}

fn __gha_escape_data(value) -> string {
  let text = to_string(value ?? "")
  return replace(replace(replace(text, "%", "%25"), "\r", "%0D"), "\n", "%0A")
}

fn __gha_escape_property(value) -> string {
  return replace(replace(__gha_escape_data(value), ":", "%3A"), ",", "%2C")
}

fn __gha_kv(key, value) {
  if value == nil {
    return nil
  }
  return key + "=" + __gha_escape_property(value)
}

fn __gha_file_path(path, fallback) {
  let explicit = path ?? fallback
  if explicit != nil && explicit != "" {
    return explicit
  }
  return nil
}

/** Escape text for the data portion of a GitHub Actions workflow command. */
pub fn gha_escape_data(value) -> string {
  return __gha_escape_data(value)
}

/** Escape text for a GitHub Actions workflow-command property. */
pub fn gha_escape_property(value) -> string {
  return __gha_escape_property(value)
}

/** Build a workflow annotation line (`::warning ...::message`). */
pub fn gha_annotation(kind: string, message: string, options: GhaAnnotationOptions = {}) -> string {
  let opts = options ?? {}
  var props = []
  for pair in [
    __gha_kv("file", opts?.file),
    __gha_kv("line", opts?.line),
    __gha_kv("endLine", opts?.endLine),
    __gha_kv("col", opts?.col),
    __gha_kv("endColumn", opts?.endColumn),
    __gha_kv("title", opts?.title),
  ] {
    if pair != nil {
      props = props.push(pair)
    }
  }
  let suffix = if len(props) > 0 {
    " " + join(props, ",")
  } else {
    ""
  }
  let annotation_kind = kind ?? "notice"
  return "::" + annotation_kind + suffix + "::" + __gha_escape_data(message)
}

/** Print a GitHub Actions notice. */
pub fn gha_notice(message: string, options: GhaAnnotationOptions = {}) {
  println(gha_annotation("notice", message, options))
}

/** Print a GitHub Actions warning. */
pub fn gha_warning(message: string, options: GhaAnnotationOptions = {}) {
  println(gha_annotation("warning", message, options))
}

/** Print a GitHub Actions error annotation. */
pub fn gha_error(message: string, options: GhaAnnotationOptions = {}) {
  println(gha_annotation("error", message, options))
}

/** Build the multiline-safe entry used by `$GITHUB_OUTPUT` and `$GITHUB_ENV`. */
pub fn gha_env_block(name: string, value, delimiter: string? = nil) -> string {
  let delim = delimiter ?? ("harn_" + uuid_v7())
  return name + "<<" + delim + "\n" + to_string(value ?? "") + "\n" + delim + "\n"
}

/** Append an output value to `$GITHUB_OUTPUT`, or to `path` when supplied. */
pub fn gha_write_output(name: string, value, path: string? = nil) -> bool {
  let target = __gha_file_path(path, env("GITHUB_OUTPUT"))
  if target == nil {
    return false
  }
  append_file(target, gha_env_block(name, value))
  return true
}

/** Append an environment value to `$GITHUB_ENV`, or to `path` when supplied. */
pub fn gha_write_env(name: string, value, path: string? = nil) -> bool {
  let target = __gha_file_path(path, env("GITHUB_ENV"))
  if target == nil {
    return false
  }
  append_file(target, gha_env_block(name, value))
  return true
}

/** Append Markdown to `$GITHUB_STEP_SUMMARY`, or to `path` when supplied. */
pub fn gha_append_summary(markdown: string, path: string? = nil) -> bool {
  let target = __gha_file_path(path, env("GITHUB_STEP_SUMMARY"))
  if target == nil {
    return false
  }
  append_file(target, markdown ?? "")
  if !ends_with(markdown ?? "", "\n") {
    append_file(target, "\n")
  }
  return true
}