@actions/core#info TypeScript Examples

The following examples show how to use @actions/core#info. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.ts    From ms-teams-deploy-card with MIT License 7 votes vote down vote up
export function renderActions(statusUrl: string, diffUrl: string) {
  const actions: PotentialAction[] = [];
  if (getInput("enable-view-status-action").toLowerCase() === "true") {
    actions.push(
      new PotentialAction(getInput("view-status-action-text"), [statusUrl])
    );
  }
  if (getInput("enable-review-diffs-action").toLowerCase() === "true") {
    actions.push(
      new PotentialAction(getInput("review-diffs-action-text"), [diffUrl])
    );
  }

  // Set custom actions
  const customActions = getInput("custom-actions");
  if (customActions && customActions.toLowerCase() !== "null") {
    try {
      let customActionsCounter = 0;
      const customActionsList = yaml.parse(customActions);
      if (Array.isArray(customActionsList)) {
        (customActionsList as any[]).forEach((action) => {
          if (
            action.text !== undefined &&
            action.url !== undefined &&
            (action.url as string).match(/https?:\/\/\S+/g)
          ) {
            actions.push(new PotentialAction(action.text, [action.url]));
            customActionsCounter++;
          }
        });
      }
      info(`Added ${customActionsCounter} custom facts.`);
    } catch {
      warning("Invalid custom-actions value.");
    }
  }
  return actions;
}
Example #2
Source File: utils.ts    From ms-teams-deploy-card with MIT License 7 votes vote down vote up
export function submitNotification(webhookBody: WebhookBody) {
  const webhookUri = getInput("webhook-uri", { required: true });
  const webhookBodyJson = JSON.stringify(webhookBody, undefined, 2);

  return fetch(webhookUri, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: webhookBodyJson,
  })
    .then((response: Response) => {
      setOutput("webhook-body", webhookBodyJson);
      info(webhookBodyJson);
      return response;
    })
    .catch(console.error);
}
Example #3
Source File: utils.ts    From ms-teams-deploy-card with MIT License 7 votes vote down vote up
export async function getOctokitCommit() {
  const runInfo = getRunInformation();
  info("Workflow run information: " + JSON.stringify(runInfo, undefined, 2));

  const githubToken = getInput("github-token", { required: true });
  const octokit = new Octokit({ auth: `token ${githubToken}` });

  return await octokit.repos.getCommit({
    owner: runInfo.owner,
    repo: runInfo.repo,
    ref: runInfo.ref || "",
  });
}
Example #4
Source File: addEnv.ts    From setup-cpp with Apache License 2.0 6 votes vote down vote up
async function addPathSystem(path: string) {
  switch (process.platform) {
    case "win32": {
      // We do not use `execa.sync(`setx PATH "${path};%PATH%"`)` because of its character limit and also because %PATH% is different for user and system
      await execPowershell(
        `$USER_PATH=([Environment]::GetEnvironmentVariable("PATH", "User")); [Environment]::SetEnvironmentVariable("PATH", "${path};$USER_PATH", "User")`
      )
      info(`${path} was added to the PATH.`)
      return
    }
    case "linux":
    case "darwin": {
      setupCppInProfile()
      appendFileSync(cpprc_path, `\nexport PATH=${path}:$PATH\n`)
      info(`${path} was added to "${cpprc_path}"`)
      return
    }
    default: {
      return
    }
  }
}
Example #5
Source File: eslint.ts    From action-eslint with MIT License 6 votes vote down vote up
runEslint = async (inputs: Inputs): Promise<void> => {
  if (!inputs.annotations) {
    disableAnnotations();
  }

  const changedFiles = await getChangedFiles(inputs.token);

  startGroup('Files changed.');
  changedFiles.forEach((file) => info(`- ${file}`));
  endGroup();

  const files = changedFiles.filter((filename) => {
    const isFileSupported = inputs.extensions.find((ext) => filename.endsWith(`.${ext}`));
    return isFileSupported;
  });

  if (files.length === 0) {
    notice('No files found. Skipping.');
    return;
  }

  startGroup('Files for linting.');
  files.forEach((file) => info(`- ${file}`));
  endGroup();

  const execOptions = [
    path.resolve(inputs.binPath, 'eslint'),
    ...files,
    ...inputs.eslintArgs,
  ].filter(Boolean);

  await exec('node', execOptions);
}
Example #6
Source File: index.ts    From retry with MIT License 6 votes vote down vote up
async function runAction() {
  await validateInputs();

  for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
    try {
      // just keep overwriting attempts output
      setOutput(OUTPUT_TOTAL_ATTEMPTS_KEY, attempt);
      await runCmd(attempt);
      info(`Command completed after ${attempt} attempt(s).`);
      break;
    } catch (error) {
      if (attempt === MAX_ATTEMPTS) {
        throw new Error(`Final attempt failed. ${error.message}`);
      } else if (!done && RETRY_ON === 'error') {
        // error: timeout
        throw error;
      } else if (RETRY_ON_EXIT_CODE && RETRY_ON_EXIT_CODE !== exit){
        throw error;
      } else if (exit > 0 && RETRY_ON === 'timeout') {
        // error: error
        throw error;
      } else {
        await runRetryCmd();
        if (WARNING_ON_RETRY) {
          warning(`Attempt ${attempt} failed. Reason: ${error.message}`);
        } else {
          info(`Attempt ${attempt} failed. Reason: ${error.message}`);
        }
      }
    }
  }
}
Example #7
Source File: index.ts    From retry with MIT License 6 votes vote down vote up
async function runRetryCmd(): Promise<void> {
  // if no retry script, just continue
  if (!ON_RETRY_COMMAND) {
    return;
  }

  try {
    await execSync(ON_RETRY_COMMAND, { stdio: 'inherit' });
  } catch (error) {
    info(`WARNING: Retry command threw the error ${error.message}`)
  }
}
Example #8
Source File: setupBrewPack.ts    From setup-cpp with Apache License 2.0 6 votes vote down vote up
/** A function that installs a package using brew */
export function setupBrewPack(name: string, version?: string): InstallationInfo {
  info(`Installing ${name} ${version ?? ""} via brew`)

  if (!hasBrew || which.sync("brew", { nothrow: true }) === null) {
    setupBrew("", "", process.arch)
    hasBrew = true
  }

  // brew is not thread-safe
  execa.sync("brew", ["install", version !== undefined && version !== "" ? `${name}@${version}` : name], {
    stdio: "inherit",
  })

  return { binDir: "/usr/local/bin/" }
}
Example #9
Source File: addEnv.ts    From setup-cpp with Apache License 2.0 6 votes vote down vote up
/// handles adding conditions to source .cpprc file from .bashrc and .profile
export function setupCppInProfile() {
  if (setupCppInProfile_called) {
    return
  }

  // a variable that prevents source_cpprc from being called from .bashrc and .profile
  const source_cpprc_str = "export SOURCE_CPPRC=0"

  if (existsSync(cpprc_path)) {
    const cpprc_content = readFileSync(cpprc_path, "utf8")
    if (cpprc_content.includes(source_cpprc_str)) {
      // already executed setupCppInProfile
      return
    }
  }

  appendFileSync(cpprc_path, `\n${source_cpprc_str}\n`)
  info(`Added ${source_cpprc_str} to ${cpprc_path}`)

  const source_cpprc_string = `\n# source .cpprc if SOURCE_CPPRC is not set to 0\nif [[ "$SOURCE_CPPRC" != 0 && -f "${cpprc_path}" ]]; then source "${cpprc_path}"; fi\n`

  try {
    // source cpprc in .profile
    const profile_path = untildify(".profile")
    appendFileSync(profile_path, source_cpprc_string)
    info(`${source_cpprc_string} was added to ${profile_path}`)

    // source cpprc in .bashrc too
    const bashrc_path = untildify(".bashrc")
    appendFileSync(bashrc_path, source_cpprc_string)
    info(`${source_cpprc_string} was added to ${bashrc_path}`)
  } catch (err) {
    warning(`Failed to add ${source_cpprc_string} to .profile or .bashrc. You should add it manually: ${err}`)
  }

  setupCppInProfile_called = true
}
Example #10
Source File: addEnv.ts    From setup-cpp with Apache License 2.0 6 votes vote down vote up
async function addEnvSystem(name: string, valGiven: string | undefined) {
  const val = valGiven ?? ""
  switch (process.platform) {
    case "win32": {
      // We do not use `execa.sync(`setx PATH "${path};%PATH%"`)` because of its character limit
      await execPowershell(`[Environment]::SetEnvironmentVariable('${name}', '${val}', "User")`)
      info(`${name}='${val}' was set in the environment.`)
      return
    }
    case "linux":
    case "darwin": {
      setupCppInProfile()
      appendFileSync(cpprc_path, `\nexport ${name}="${val}"\n`)
      info(`${name}="${val}" was added to "${cpprc_path}`)
      return
    }
    default: {
      // fall through shell path modification
    }
  }
  process.env[name] = val
}
Example #11
Source File: setupPipPack.ts    From setup-cpp with Apache License 2.0 5 votes vote down vote up
/** A function that installs a package using pip */
export async function setupPipPack(name: string, version?: string): Promise<InstallationInfo> {
  info(`Installing ${name} ${version ?? ""} via pip`)

  // setup python and pip if needed
  if (python === undefined) {
    if (which.sync("python3", { nothrow: true }) !== null) {
      python = "python3"
    } else if (which.sync("python", { nothrow: true }) !== null && (await isBinUptoDate("python", "3.0.0"))) {
      python = "python"
    } else {
      info("python3 was not found. Installing python")
      await setupPython(getVersion("python", undefined), "", process.arch)
      // try again
      if (tried) {
        throw new Error("Failed to install python")
      }
      tried = true
      return setupPipPack(name, version)
    }
    if (process.platform === "win32") {
      // downgrade pip on Windows
      // https://github.com/pypa/pip/issues/10875#issuecomment-1030293005
      execa.sync(python, ["-m", "pip", "install", "-U", "pip==21.3.1"], { stdio: "inherit" })
    } else if (process.platform === "linux") {
      // ensure that pip is installed on Linux (happens when python is found but pip not installed)
      setupAptPack("python3-pip")
    }

    // install wheel (required for Conan, Meson, etc.)
    execa.sync(python, ["-m", "pip", "install", "-U", "wheel"], { stdio: "inherit" })
  }

  execa.sync(python, ["-m", "pip", "install", version !== undefined && version !== "" ? `${name}==${version}` : name], {
    stdio: "inherit",
  })

  if (binDir === undefined) {
    if (process.platform === "linux") {
      binDir = "/home/runner/.local/bin/"
    } else if (process.platform === "darwin") {
      binDir = "/usr/local/bin/"
    } else {
      // windows or others
      try {
        binDir = join(
          (await getExecOutput(`${python} -c "import sys;print(sys.base_exec_prefix);"`)).stdout.trim(),
          "Scripts"
        )
      } catch {
        binDir = join(
          (await getExecOutput(`${python} -c "import sys;print(sys.base_exec_prefix);"`)).stdout.trim(),
          "Scripts"
        )
      }
    }
    info(`${binDir} to PATH`)
    await addPath(binDir)
  }

  return { binDir }
}
Example #12
Source File: index.ts    From auto-changelog with MIT License 5 votes vote down vote up
async function run() {
  const inputs = await getInputs();

  const octokit = getOctokit(getToken());

  const {
    repo: { owner, repo },
    sha,
  } = context;

  let semver: SemVer.SemVer | null = null;

  if (inputs.semver) {
    semver = SemVer.parse(inputs.releaseName, { includePrerelease: true });

    if (semver == null)
      return setFailed(
        `Expected a semver compatible releaseName, got "${inputs.releaseName}" instead.`,
      );
  }

  let prerelease = false;

  if (semver != null) prerelease = semver.prerelease.length > 0;

  const { sha: tagRef, name: tagName } = await getTagSha({
    octokit,
    owner,
    repo,
    sha,
    semver,
    prerelease,
  });

  let changelog = await generate({
    octokit,
    owner,
    repo,
    sha,
    tagRef,
    inputs,
  });

  if (inputs.mentionNewContributors) {
    const { data } = await octokit.rest.repos.generateReleaseNotes({
      owner,
      repo,
      tag_name: inputs.releaseName,
      previous_tag_name: tagName,
    });

    const tokens = marked.lexer(data.body);

    const index = tokens.findIndex(
      (token) => token.type === "heading" && token.text === "New Contributors",
    );

    const token = tokens[index + 1];

    if (token.type === "list")
      changelog += `\n\n## New Contributors\n${token.raw}\n`;
  }

  if (inputs.includeCompare && tagName != null) {
    changelog += `\n\n**Full Changelog**: https://github.com/${owner}/${repo}/compare/${tagName}...${inputs.releaseName}`;
  }

  info(`-> prerelease: ${prerelease}`);

  setOutput("prerelease", prerelease);

  info(`-> changelog: "${changelog}"`);

  setOutput("changelog", changelog);
}
Example #13
Source File: setupChocoPack.ts    From setup-cpp with Apache License 2.0 5 votes vote down vote up
/** A function that installs a package using choco */
export async function setupChocoPack(name: string, version?: string, args: string[] = []): Promise<InstallationInfo> {
  info(`Installing ${name} ${version ?? ""} via chocolatey`)

  if (!hasChoco || which.sync("choco", { nothrow: true }) === null) {
    await setupChocolatey("", "", process.arch)
    hasChoco = true
  }

  // https://github.com/jberezanski/ChocolateyPackages/issues/97#issuecomment-986825694
  const PATH = process.env.PATH
  const env = { ...process.env }
  delete env.TMP
  delete env.TEMP
  delete env.Path
  env.PATH = PATH

  if (version !== undefined && version !== "") {
    execa.sync("choco", ["install", "-y", name, `--version=${version}`, ...args], {
      env,
      extendEnv: false,
      stdio: "inherit",
    })
  } else {
    try {
      execa.sync("choco", ["install", "-y", name, ...args], { env, extendEnv: false, stdio: "inherit" })
    } catch (err) {
      // if the package requires a reboot, downgrade the error to a notice
      if ((err as Error).message.includes("exit code 3010")) {
        notice(`${name} might require a reboot for the completion of the installation.`)
      } else {
        throw err
      }
    }
  }

  const binDir = `${process.env.ChocolateyInstall ?? "C:/ProgramData/chocolatey"}/bin`
  await addPath(binDir)

  return { binDir }
}
Example #14
Source File: annotations.ts    From action-eslint with MIT License 5 votes vote down vote up
disableAnnotations = (): void => {
  debug('Disabling Annotations');
  info('##[remove-matcher owner=eslint-compact]');
  info('##[remove-matcher owner=eslint-stylish]');
}
Example #15
Source File: setupAptPack.ts    From setup-cpp with Apache License 2.0 5 votes vote down vote up
/** A function that installs a package using apt */
export function setupAptPack(
  name: string,
  version?: string,
  repositories: boolean | string[] = true
): InstallationInfo {
  info(`Installing ${name} ${version ?? ""} via apt`)

  const apt = "apt-get"

  process.env.DEBIAN_FRONTEND = "noninteractive"

  if (!didUpdate) {
    execSudo(apt, ["update", "-y"])
    didUpdate = true
  }

  if (!didInit) {
    // install apt utils and certificates (usually missing from docker containers)
    // set time - zone
    // TZ = Canada / Pacific
    // ln - snf / usr / share / zoneinfo / $TZ / etc / localtime && echo $TZ > /etc/timezone
    execSudo(apt, [
      "install",
      "--fix-broken",
      "-y",
      "software-properties-common",
      "apt-utils",
      "ca-certificates",
      "gnupg",
    ])
    try {
      execSudo("apt-key", ["adv", "--keyserver", "keyserver.ubuntu.com", "--recv-keys", "3B4FE6ACC0B21F32"])
      execSudo("apt-key", ["adv", "--keyserver", "keyserver.ubuntu.com", "--recv-keys", "40976EAF437D05B5"])
      execSudo("apt-key", ["adv", "--keyserver", "keyserver.ubuntu.com", "--recv-keys", "1E9377A2BA9EF27F"])
    } catch (err) {
      warning(`Failed to add keys: ${err}`)
    }
    didInit = true
  }

  if (Array.isArray(repositories)) {
    for (const repo of repositories) {
      // eslint-disable-next-line no-await-in-loop
      execSudo("add-apt-repository", ["--update", "-y", repo])
    }
    execSudo(apt, ["update", "-y"])
  }

  if (version !== undefined && version !== "") {
    try {
      execSudo(apt, ["install", "--fix-broken", "-y", `${name}=${version}`])
    } catch {
      execSudo(apt, ["install", "--fix-broken", "-y", `${name}-${version}`])
    }
  } else {
    execSudo(apt, ["install", "--fix-broken", "-y", name])
  }

  return { binDir: "/usr/bin/" }
}
Example #16
Source File: setupBin.ts    From setup-cpp with Apache License 2.0 4 votes vote down vote up
/**
 * A function that:
 *
 * - Downloads and extracts a package
 * - Adds the bin path of the package to PATH
 * - Caches the downloaded directory into tool cache for usage from other sessions
 *
 * @returns The installation directory
 */
export async function setupBin(
  name: string,
  version: string,
  getPackageInfo: (version: string, platform: NodeJS.Platform, arch: string) => PackageInfo | Promise<PackageInfo>,
  setupDir: string,
  arch: string
): Promise<InstallationInfo> {
  info(`Installing ${name} ${version} ${arch} via direct downloading`)

  process.env.RUNNER_TEMP = process.env.RUNNER_TEMP ?? tmpdir()
  process.env.RUNNER_TOOL_CACHE = process.env.RUNNER_TOOL_CACHE ?? join(tmpdir(), "setup-cpp", "hostedtoolcache")

  const { url, binRelativeDir, binFileName, extractedFolderName, extractFunction } = await getPackageInfo(
    version,
    process.platform,
    arch
  )

  // Restore from cache (if found).
  if (isGitHubCI()) {
    try {
      const dir = find(name, version)
      if (dir) {
        const installDir = join(dir, extractedFolderName)
        const binDir = join(installDir, binRelativeDir)
        if (existsSync(binDir) && existsSync(join(binDir, binFileName))) {
          info(`${name} ${version} was found in the cache at ${binDir}.`)
          await addPath(binDir)

          return { installDir, binDir }
        }
      }
    } catch {
      // fails on a local machine?
    }
  }

  const installDir = join(setupDir, extractedFolderName)
  const binDir = join(installDir, binRelativeDir)
  const binFile = join(binDir, binFileName)

  // download ane extract the package into the installation directory.
  if (!existsSync(binDir) || !existsSync(binFile)) {
    info(`Download and extract ${name} ${version}`)

    if (!didInit) {
      if (process.platform === "linux") {
        // extraction dependencies
        setupAptPack("unzip")
        setupAptPack("tar")
        setupAptPack("xz-utils")
      }
      // eslint-disable-next-line require-atomic-updates
      didInit = true
    }

    try {
      const downloaded = await downloadTool(url)
      await extractFunction?.(downloaded, setupDir)
    } catch (err) {
      throw new Error(`Failed to download ${name} ${version} ${arch}: ${err}`)
    }
  }

  // Adding the bin dir to the path
  /** The directory which the tool is installed to */
  info(`Add ${binDir} to PATH`)
  await addPath(binDir)

  // check if inside Github Actions. If so, cache the installation
  if (isGitHubCI() && typeof process.env.RUNNER_TOOL_CACHE === "string") {
    await cacheDir(setupDir, name, version)
  }

  return { installDir, binDir }
}
Example #17
Source File: complete.ts    From ms-teams-deploy-card with MIT License 4 votes vote down vote up
export function formatCompleteLayout(
  commit: Octokit.Response<Octokit.ReposGetCommitResponse>,
  conclusion: string,
  elapsedSeconds?: number
) {
  const repoUrl = `https://github.com/${process.env.GITHUB_REPOSITORY}`;
  const branchUrl = `${repoUrl}/tree/${process.env.GITHUB_REF}`;
  const webhookBody = formatCozyLayout(commit, conclusion, elapsedSeconds);
  const section = webhookBody.sections[0];

  // for complete layout, just replace activityText with potentialAction
  section.activityText = undefined;
  section.potentialAction = renderActions(
    `${repoUrl}/actions/runs/${process.env.GITHUB_RUN_ID}`,
    commit.data.html_url
  );

  // Set status and elapsedSeconds
  let labels = `\`${conclusion.toUpperCase()}\``;
  if (elapsedSeconds) {
    labels = `\`${conclusion.toUpperCase()} [${elapsedSeconds}s]\``;
  }

  // Set section facts
  section.facts = [
    new Fact(
      "Event type:",
      "`" + process.env.GITHUB_EVENT_NAME?.toUpperCase() + "`"
    ),
    new Fact("Status:", labels),
    new Fact(
      "Commit message:",
      escapeMarkdownTokens(commit.data.commit.message)
    ),
    new Fact("Repository & branch:", `[${branchUrl}](${branchUrl})`),
  ];

  // Set custom facts
  const customFacts = getInput("custom-facts");
  if (customFacts && customFacts.toLowerCase() !== "null") {
    try {
      let customFactsCounter = 0;
      const customFactsList = yaml.parse(customFacts);
      if (Array.isArray(customFactsList)) {
        (customFactsList as any[]).forEach((fact) => {
          if (fact.name !== undefined && fact.value !== undefined) {
            section.facts?.push(new Fact(fact.name + ":", fact.value));
            customFactsCounter++;
          }
        });
      }
      info(`Added ${customFactsCounter} custom facts.`);
    } catch {
      warning("Invalid custom-facts value.");
    }
  }

  // Set environment name
  const environment = getInput("environment");
  if (environment !== "") {
    section.facts.splice(
      1,
      0,
      new Fact("Environment:", `\`${environment.toUpperCase()}\``)
    );
  }

  // Set list of files
  if (getInput("include-files").toLowerCase() === "true") {
    const allowedFileLen = getInput("allowed-file-len").toLowerCase();
    const allowedFileLenParsed = parseInt(
      allowedFileLen === "" ? "7" : allowedFileLen
    );
    const filesToDisplay = formatFilesToDisplay(
      commit.data.files,
      allowedFileLenParsed,
      commit.data.html_url
    );
    section.facts?.push({
      name: "Files changed:",
      value: filesToDisplay,
    });
  }

  return webhookBody;
}