fix: make GitHub Actions checks opt-in for outdated and update (#13259)
Checking GitHub Actions for updates spawns `git ls-remote` against every repository referenced by the workflow files. That reaches the network in a way pnpm cannot validate up front, and it fails wherever GitHub is not reachable the way pnpm assumes: a GitHub Enterprise Server hosting the actions (pnpm/pnpm#13220), a container with a custom certificate authority (pnpm/pnpm#13254), an offline or proxied CI network. Both reports came within days of the feature shipping, and neither is fixable from pnpm's side, so the check no longer runs unless it is asked for. `pnpm outdated` and `pnpm update` — interactive or not, recursive or not — now read workflow files only with `--include-github-actions` or with `update.githubActions` set to `true`. `update.githubActions: false` keeps working; it is now equivalent to leaving the setting unset, so anyone who added it to silence the warnings needs no change. The opt-in rule lives in one place per stack (`shouldCheckGitHubActions` and `github_actions::opted_in`) and is shared by every call site, so the commands cannot drift apart again. `pnpm outdated` gained the `--include-github-actions` flag it was missing. Closes pnpm/pnpm#13254
This commit is contained in:
1 parent
f4ebdb9de8
commit
83d04aa232
14 files changed
+251
-40
No files matched your search
@@ -0,0 +1,12 @@
|
||||
---
|
||||
"@pnpm/deps.github-actions": patch
|
||||
"@pnpm/deps.inspection.commands": patch
|
||||
"@pnpm/installing.commands": patch
|
||||
"@pnpm/types": patch
|
||||
"pacquet": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
Checking GitHub Actions dependencies for updates is now opt-in for every command. Neither `pnpm outdated` nor `pnpm update` reads the workflow files unless `--include-github-actions` is passed or `update.githubActions` is set to `true` in `pnpm-workspace.yaml`. Reading them runs `git ls-remote` against every referenced repository, which fails in environments where GitHub is not reachable the way pnpm assumes (a GitHub Enterprise Server, a custom certificate authority, or an offline network) [#13254](https://github.com/pnpm/pnpm/issues/13254).
|
||||
|
||||
`pnpm outdated` accepts the `--include-github-actions` option too.
|
||||
@@ -384,6 +384,10 @@ pub struct OutdatedArgs {
|
||||
#[clap(long, value_enum)]
|
||||
pub sort_by: Option<SortBy>,
|
||||
|
||||
/// Also check GitHub Actions dependencies in workflow and action files.
|
||||
#[clap(long = "include-github-actions")]
|
||||
pub include_github_actions: bool,
|
||||
|
||||
/// Check globally installed packages.
|
||||
#[clap(short = 'g', long)]
|
||||
pub global: bool,
|
||||
@@ -485,7 +489,7 @@ impl OutdatedArgs {
|
||||
Vec::new()
|
||||
};
|
||||
if include.contains(&DependencyGroup::Dev)
|
||||
&& config.update_config.github_actions != Some(false)
|
||||
&& github_actions::opted_in(self.include_github_actions, config)
|
||||
{
|
||||
let actions = github_actions::find_outdated::<Reporter>(
|
||||
root,
|
||||
@@ -622,7 +626,7 @@ impl OutdatedArgs {
|
||||
}
|
||||
|
||||
if include.contains(&DependencyGroup::Dev)
|
||||
&& config.update_config.github_actions != Some(false)
|
||||
&& github_actions::opted_in(self.include_github_actions, config)
|
||||
{
|
||||
let action_matcher = github_actions::selector_matcher(&self.packages);
|
||||
let actions = github_actions::find_outdated::<Reporter>(
|
||||
|
||||
@@ -395,9 +395,7 @@ impl UpdateArgs {
|
||||
include_direct.contains(&DependencyGroup::Dev)
|
||||
&& !self.no_save
|
||||
&& !self.lockfile_only
|
||||
&& ((self.interactive && config.update_config.github_actions != Some(false))
|
||||
|| self.include_github_actions
|
||||
|| config.update_config.github_actions == Some(true))
|
||||
&& github_actions::opted_in(self.include_github_actions, config)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,25 +56,30 @@ fn prod_with_no_optional_drops_optional() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn github_actions_are_opt_in_except_for_interactive_updates() {
|
||||
fn github_actions_are_opt_in_for_every_update() {
|
||||
let include_direct = vec![DependencyGroup::Prod, DependencyGroup::Dev];
|
||||
let mut config = Config::new();
|
||||
|
||||
assert!(!update_args(&[]).should_update_github_actions(&config, &include_direct));
|
||||
assert!(
|
||||
!update_args(&["--interactive"]).should_update_github_actions(&config, &include_direct),
|
||||
);
|
||||
assert!(
|
||||
update_args(&["--include-github-actions"])
|
||||
.should_update_github_actions(&config, &include_direct),
|
||||
);
|
||||
assert!(update_args(&["--interactive"]).should_update_github_actions(&config, &include_direct));
|
||||
assert!(
|
||||
update_args(&["--interactive", "--include-github-actions"])
|
||||
.should_update_github_actions(&config, &include_direct),
|
||||
);
|
||||
|
||||
config.update_config.github_actions = Some(true);
|
||||
assert!(update_args(&[]).should_update_github_actions(&config, &include_direct));
|
||||
assert!(update_args(&["--interactive"]).should_update_github_actions(&config, &include_direct));
|
||||
assert!(
|
||||
!update_args(&["--prod"]).should_update_github_actions(&config, &[DependencyGroup::Prod],),
|
||||
);
|
||||
|
||||
// An explicit `false` opts interactive updates out of GitHub Actions,
|
||||
// but never overrides the explicit `--include-github-actions` flag.
|
||||
config.update_config.github_actions = Some(false);
|
||||
assert!(
|
||||
!update_args(&["--interactive"]).should_update_github_actions(&config, &include_direct),
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
use futures_util::{StreamExt, stream};
|
||||
use node_semver::{Range as SemverRange, Version};
|
||||
use pacquet_config::matcher::{Matcher, create_matcher};
|
||||
use pacquet_config::{
|
||||
Config,
|
||||
matcher::{Matcher, create_matcher},
|
||||
};
|
||||
use pacquet_network::redact_and_sanitize;
|
||||
use pacquet_reporter::{GlobalLog, LogEvent, LogLevel, Reporter};
|
||||
use pacquet_resolving_git_resolver::{GitCommandRunner, RealGitRunner, get_repo_refs};
|
||||
@@ -73,6 +76,14 @@ struct PlannedUpdate {
|
||||
|
||||
const GIT_CONCURRENCY: usize = 8;
|
||||
|
||||
/// GitHub Actions dependencies are opt-in. Reading them means running `git
|
||||
/// ls-remote` against every referenced repository, so `pnpm outdated` and
|
||||
/// `pnpm update` only look at workflow files when asked to, either with
|
||||
/// `--include-github-actions` or with `update.githubActions: true`.
|
||||
pub fn opted_in(include_github_actions: bool, config: &Config) -> bool {
|
||||
include_github_actions || config.update_config.github_actions == Some(true)
|
||||
}
|
||||
|
||||
pub async fn find_outdated<Reporter: self::Reporter>(
|
||||
root: &Path,
|
||||
compatible: bool,
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use super::{
|
||||
ActionReference, RepoVersion, find_current, find_outdated_with_runner, is_selector,
|
||||
normalize_selector, render_target_ref, render_target_value,
|
||||
normalize_selector, opted_in, render_target_ref, render_target_value,
|
||||
repo_versions as versions_from_refs, selector_matcher, split_uses_value, update_with_runner,
|
||||
};
|
||||
use node_semver::Version;
|
||||
use pacquet_config::Config;
|
||||
use pacquet_reporter::{GlobalLog, LogEvent, LogLevel, Reporter, SilentReporter};
|
||||
use pacquet_resolving_git_resolver::{GitCommandRunner, GitRunError};
|
||||
use std::{collections::HashMap, fs, future::Future, path::PathBuf, pin::Pin, sync::Mutex};
|
||||
@@ -77,6 +78,20 @@ impl GitCommandRunner for PreOneGitRunner {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn workflow_files_are_read_only_when_opted_in() {
|
||||
let mut config = Config::new();
|
||||
assert!(!opted_in(false, &config));
|
||||
assert!(opted_in(true, &config));
|
||||
|
||||
config.update_config.github_actions = Some(false);
|
||||
assert!(!opted_in(false, &config));
|
||||
assert!(opted_in(true, &config));
|
||||
|
||||
config.update_config.github_actions = Some(true);
|
||||
assert!(opted_in(false, &config));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn distinguishes_action_selectors_from_package_selectors() {
|
||||
assert_eq!(
|
||||
|
||||
@@ -537,10 +537,10 @@ pub struct UpdateSettings {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub changeset: Option<bool>,
|
||||
|
||||
/// Whether `pnpm update` should also update GitHub Actions
|
||||
/// dependencies. When explicitly set to `false`, `pnpm outdated`
|
||||
/// and the interactive `pnpm update` skip GitHub Actions
|
||||
/// dependencies as well.
|
||||
/// Whether `pnpm outdated` and `pnpm update` should also look at
|
||||
/// the GitHub Actions referenced by the workflow files. Opt-in:
|
||||
/// neither command reads them unless this is set to `true` or
|
||||
/// `--include-github-actions` is passed.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub github_actions: Option<bool>,
|
||||
|
||||
@@ -569,10 +569,10 @@ pub struct UpdateConfig {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub ignore_dependencies: Option<Vec<String>>,
|
||||
|
||||
/// Whether `pnpm update` should also update GitHub Actions
|
||||
/// dependencies. When explicitly set to `false`, `pnpm outdated`
|
||||
/// and the interactive `pnpm update` skip GitHub Actions
|
||||
/// dependencies as well.
|
||||
/// Whether `pnpm outdated` and `pnpm update` should also look at
|
||||
/// the GitHub Actions referenced by the workflow files. Opt-in:
|
||||
/// neither command reads them unless this is set to `true` or
|
||||
/// `--include-github-actions` is passed.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub github_actions: Option<bool>,
|
||||
|
||||
|
||||
@@ -208,9 +208,9 @@ export interface UpdateSettings {
|
||||
*/
|
||||
changeset?: boolean
|
||||
/**
|
||||
* Whether `pnpm update` should also update GitHub Actions dependencies.
|
||||
* When explicitly set to `false`, `pnpm outdated` and the interactive
|
||||
* `pnpm update` skip GitHub Actions dependencies as well.
|
||||
* Whether `pnpm outdated` and `pnpm update` should also look at the GitHub
|
||||
* Actions referenced by the workflow files. Opt-in: neither command reads
|
||||
* them unless this is set to `true` or `--include-github-actions` is passed.
|
||||
*/
|
||||
githubActions?: boolean
|
||||
/**
|
||||
|
||||
@@ -72,6 +72,21 @@ interface PlannedUpdate {
|
||||
const SHA_PATTERN = /^[0-9a-f]{40}$/
|
||||
const limitRepoReads = pLimit(8)
|
||||
|
||||
export interface GitHubActionsOptInOptions {
|
||||
includeGithubActions?: boolean
|
||||
updateConfig?: { githubActions?: boolean }
|
||||
}
|
||||
|
||||
/**
|
||||
* GitHub Actions dependencies are opt-in. Reading them means running
|
||||
* `git ls-remote` against every referenced repository, so `pnpm outdated` and
|
||||
* `pnpm update` only look at workflow files when asked to, either with
|
||||
* `--include-github-actions` or with `update.githubActions: true`.
|
||||
*/
|
||||
export function shouldCheckGitHubActions (opts: GitHubActionsOptInOptions): boolean {
|
||||
return opts.includeGithubActions === true || opts.updateConfig?.githubActions === true
|
||||
}
|
||||
|
||||
export function isGitHubActionSelector (selector: string): boolean {
|
||||
const pattern = selector.startsWith('!') ? selector.slice(1) : selector
|
||||
return !pattern.startsWith('@') && pattern.includes('/')
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
import { colorizeSemverDiff } from '@pnpm/colorize-semver-diff'
|
||||
import { createMatcher } from '@pnpm/config.matcher'
|
||||
import { type Config, type ConfigContext, types as allTypes } from '@pnpm/config.reader'
|
||||
import { findOutdatedGitHubActions, isGitHubActionSelector, normalizeGitHubActionSelector } from '@pnpm/deps.github-actions'
|
||||
import { findOutdatedGitHubActions, isGitHubActionSelector, normalizeGitHubActionSelector, shouldCheckGitHubActions } from '@pnpm/deps.github-actions'
|
||||
import {
|
||||
outdatedDepsOfProjects,
|
||||
type OutdatedPackage,
|
||||
@@ -51,6 +51,7 @@ export function rcOptionsTypes (): Record<string, unknown> {
|
||||
|
||||
export const cliOptionsTypes = (): Record<string, unknown> => ({
|
||||
...rcOptionsTypes(),
|
||||
'include-github-actions': Boolean,
|
||||
recursive: Boolean,
|
||||
})
|
||||
|
||||
@@ -66,7 +67,7 @@ export const commandNames = ['outdated']
|
||||
|
||||
export function help (): string {
|
||||
return renderHelp({
|
||||
description: `Check for outdated package and GitHub Actions dependencies. The check can be limited to a subset of dependencies by providing arguments (patterns are supported).
|
||||
description: `Check for outdated package dependencies. GitHub Actions dependencies can be included with --include-github-actions. The check can be limited to a subset of dependencies by providing arguments (patterns are supported).
|
||||
|
||||
Examples:
|
||||
pnpm outdated
|
||||
@@ -115,6 +116,10 @@ For options that may be used with `-r`, see "pnpm help recursive"',
|
||||
description: 'Prints the outdated dependencies in the given format. Default is "table". Supported options: "table, list, json"',
|
||||
name: '--format <format>',
|
||||
},
|
||||
{
|
||||
description: 'Also check GitHub Actions dependencies in workflow and action files',
|
||||
name: '--include-github-actions',
|
||||
},
|
||||
{
|
||||
description: 'Specify the sorting method. Currently only `name` is supported.',
|
||||
name: '--sort-by',
|
||||
@@ -136,6 +141,7 @@ export const completion: CompletionFunc = async (cliOpts) => {
|
||||
|
||||
export type OutdatedCommandOptions = {
|
||||
compatible?: boolean
|
||||
includeGithubActions?: boolean
|
||||
long?: boolean
|
||||
recursive?: boolean
|
||||
format?: 'table' | 'list' | 'json'
|
||||
@@ -228,7 +234,7 @@ export async function handler (
|
||||
timeout: opts.fetchTimeout,
|
||||
})
|
||||
: [],
|
||||
opts.global || !include.devDependencies || opts.updateConfig?.githubActions === false
|
||||
opts.global || !include.devDependencies || !shouldCheckGitHubActions(opts)
|
||||
? []
|
||||
: findOutdatedGitHubActions({
|
||||
compatible: opts.compatible,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { TABLE_OPTIONS } from '@pnpm/cli.utils'
|
||||
import { createMatcher } from '@pnpm/config.matcher'
|
||||
import { findOutdatedGitHubActions, isGitHubActionSelector, normalizeGitHubActionSelector } from '@pnpm/deps.github-actions'
|
||||
import { findOutdatedGitHubActions, isGitHubActionSelector, normalizeGitHubActionSelector, shouldCheckGitHubActions } from '@pnpm/deps.github-actions'
|
||||
import {
|
||||
outdatedDepsOfProjects,
|
||||
} from '@pnpm/deps.inspection.outdated'
|
||||
@@ -83,7 +83,7 @@ export async function outdatedRecursive (
|
||||
outdatedMap[key].dependentPkgs.push({ location: rootDir, manifest })
|
||||
}
|
||||
}
|
||||
if (opts.include.devDependencies && opts.updateConfig?.githubActions !== false) {
|
||||
if (opts.include.devDependencies && shouldCheckGitHubActions(opts)) {
|
||||
const outdatedActions = await findOutdatedGitHubActions({
|
||||
compatible: opts.compatible,
|
||||
dir: opts.workspaceDir ?? opts.lockfileDir ?? opts.dir,
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
|
||||
import { beforeEach, expect, jest, test } from '@jest/globals'
|
||||
import { prepare, preparePackages } from '@pnpm/prepare'
|
||||
import { filterProjectsBySelectorObjectsFromDir } from '@pnpm/workspace.projects-filter'
|
||||
|
||||
import { DEFAULT_OUTDATED_OPTS } from './utils/index.js'
|
||||
|
||||
const originalModule = await import('@pnpm/deps.github-actions')
|
||||
jest.unstable_mockModule('@pnpm/deps.github-actions', () => {
|
||||
return {
|
||||
...originalModule,
|
||||
findOutdatedGitHubActions: jest.fn(async () => []),
|
||||
}
|
||||
})
|
||||
|
||||
const { findOutdatedGitHubActions } = await import('@pnpm/deps.github-actions')
|
||||
const { handler } = await import('../../src/outdated/outdated.js')
|
||||
|
||||
beforeEach(() => {
|
||||
jest.mocked(findOutdatedGitHubActions).mockClear()
|
||||
})
|
||||
|
||||
test('outdated does not look at GitHub Actions by default', async () => {
|
||||
prepare({})
|
||||
writeWorkflow()
|
||||
|
||||
await handler({ ...DEFAULT_OUTDATED_OPTS, dir: process.cwd() })
|
||||
|
||||
expect(findOutdatedGitHubActions).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test('outdated looks at GitHub Actions with --include-github-actions', async () => {
|
||||
prepare({})
|
||||
writeWorkflow()
|
||||
|
||||
await handler({ ...DEFAULT_OUTDATED_OPTS, dir: process.cwd(), includeGithubActions: true })
|
||||
|
||||
expect(findOutdatedGitHubActions).toHaveBeenCalledWith(expect.objectContaining({ dir: process.cwd() }))
|
||||
})
|
||||
|
||||
test('outdated looks at GitHub Actions when update.githubActions is true', async () => {
|
||||
prepare({})
|
||||
writeWorkflow()
|
||||
|
||||
await handler({ ...DEFAULT_OUTDATED_OPTS, dir: process.cwd(), updateConfig: { githubActions: true } })
|
||||
|
||||
expect(findOutdatedGitHubActions).toHaveBeenCalledWith(expect.objectContaining({ dir: process.cwd() }))
|
||||
})
|
||||
|
||||
test('recursive outdated does not look at GitHub Actions by default', async () => {
|
||||
preparePackages([
|
||||
{
|
||||
name: 'project-1',
|
||||
version: '1.0.0',
|
||||
},
|
||||
])
|
||||
writeWorkflow()
|
||||
const { allProjects, selectedProjectsGraph } = await filterProjectsBySelectorObjectsFromDir(process.cwd(), [])
|
||||
const opts = {
|
||||
...DEFAULT_OUTDATED_OPTS,
|
||||
allProjects,
|
||||
dir: process.cwd(),
|
||||
recursive: true,
|
||||
selectedProjectsGraph,
|
||||
workspaceDir: process.cwd(),
|
||||
}
|
||||
|
||||
await handler(opts)
|
||||
|
||||
expect(findOutdatedGitHubActions).not.toHaveBeenCalled()
|
||||
|
||||
await handler({ ...opts, includeGithubActions: true })
|
||||
|
||||
expect(findOutdatedGitHubActions).toHaveBeenCalledWith(expect.objectContaining({ dir: process.cwd() }))
|
||||
})
|
||||
|
||||
function writeWorkflow (): void {
|
||||
fs.mkdirSync(path.join('.github', 'workflows'), { recursive: true })
|
||||
fs.writeFileSync(path.join('.github', 'workflows', 'ci.yml'), `jobs:
|
||||
test:
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.0
|
||||
`)
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
} from '@pnpm/cli.utils'
|
||||
import { createMatcher } from '@pnpm/config.matcher'
|
||||
import { types as allTypes } from '@pnpm/config.reader'
|
||||
import { findOutdatedGitHubActions, isGitHubActionSelector, normalizeGitHubActionSelector, updateGitHubActions } from '@pnpm/deps.github-actions'
|
||||
import { findOutdatedGitHubActions, isGitHubActionSelector, normalizeGitHubActionSelector, shouldCheckGitHubActions, updateGitHubActions } from '@pnpm/deps.github-actions'
|
||||
import { outdatedDepsOfProjects } from '@pnpm/deps.inspection.outdated'
|
||||
import { PnpmError } from '@pnpm/error'
|
||||
import { handleGlobalUpdate } from '@pnpm/global.commands'
|
||||
@@ -243,8 +243,7 @@ async function interactiveUpdate (
|
||||
timeout: opts.fetchTimeout,
|
||||
})
|
||||
: projects.map(() => []),
|
||||
include.devDependencies && opts.save !== false && !opts.lockfileOnly &&
|
||||
(opts.updateConfig?.githubActions !== false || opts.includeGithubActions === true)
|
||||
shouldUpdateGitHubActions(opts, include)
|
||||
? findOutdatedGitHubActions({
|
||||
compatible: opts.latest !== true,
|
||||
dir: opts.workspaceDir ?? opts.lockfileDir ?? opts.dir,
|
||||
@@ -326,12 +325,7 @@ async function interactiveUpdate (
|
||||
throw err
|
||||
}
|
||||
|
||||
// An explicit `update.githubActions: false` must survive into the update
|
||||
// phase — only the `--include-github-actions` flag may override it.
|
||||
return update(updatePkgNames, {
|
||||
...opts,
|
||||
includeGithubActions: opts.includeGithubActions === true || opts.updateConfig?.githubActions !== false,
|
||||
}, rebuildHandler) as Promise<undefined>
|
||||
return update(updatePkgNames, opts, rebuildHandler) as Promise<undefined>
|
||||
}
|
||||
|
||||
async function update (
|
||||
@@ -340,10 +334,7 @@ async function update (
|
||||
rebuildHandler?: CommandHandler
|
||||
): Promise<void> {
|
||||
const includeDirect = makeIncludeDependenciesFromCLI(opts.cliOptions)
|
||||
const updateActions = includeDirect.devDependencies &&
|
||||
opts.save !== false &&
|
||||
!opts.lockfileOnly &&
|
||||
(opts.includeGithubActions === true || opts.updateConfig?.githubActions === true)
|
||||
const updateActions = shouldUpdateGitHubActions(opts, includeDirect)
|
||||
if (opts.latest) {
|
||||
const dependenciesWithTags = dependencies.filter((name) =>
|
||||
(!updateActions || !isGitHubActionSelector(name)) && parseUpdateParam(name).versionSpec != null)
|
||||
@@ -407,6 +398,13 @@ async function update (
|
||||
}
|
||||
}
|
||||
|
||||
function shouldUpdateGitHubActions (opts: UpdateCommandOptions, include: IncludedDependencies): boolean {
|
||||
return include.devDependencies &&
|
||||
opts.save !== false &&
|
||||
!opts.lockfileOnly &&
|
||||
shouldCheckGitHubActions(opts)
|
||||
}
|
||||
|
||||
function makeIncludeDependenciesFromCLI (opts: {
|
||||
production?: boolean
|
||||
dev?: boolean
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
|
||||
import { beforeEach, expect, jest, test } from '@jest/globals'
|
||||
import { prepare } from '@pnpm/prepare'
|
||||
|
||||
import { DEFAULT_OPTS } from '../utils/index.js'
|
||||
|
||||
const originalModule = await import('@pnpm/deps.github-actions')
|
||||
jest.unstable_mockModule('@pnpm/deps.github-actions', () => {
|
||||
return {
|
||||
...originalModule,
|
||||
findOutdatedGitHubActions: jest.fn(async () => []),
|
||||
}
|
||||
})
|
||||
|
||||
const { findOutdatedGitHubActions } = await import('@pnpm/deps.github-actions')
|
||||
const { handler } = await import('../../src/update/index.js')
|
||||
|
||||
beforeEach(() => {
|
||||
jest.mocked(findOutdatedGitHubActions).mockClear()
|
||||
prepare({})
|
||||
fs.mkdirSync(path.join('.github', 'workflows'), { recursive: true })
|
||||
fs.writeFileSync(path.join('.github', 'workflows', 'ci.yml'), `jobs:
|
||||
test:
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.0
|
||||
`)
|
||||
})
|
||||
|
||||
test('update --interactive does not look for GitHub Actions updates by default', async () => {
|
||||
await handler({
|
||||
...DEFAULT_OPTS,
|
||||
dir: process.cwd(),
|
||||
interactive: true,
|
||||
})
|
||||
|
||||
expect(findOutdatedGitHubActions).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test('update --interactive looks for GitHub Actions updates with --include-github-actions', async () => {
|
||||
await handler({
|
||||
...DEFAULT_OPTS,
|
||||
dir: process.cwd(),
|
||||
includeGithubActions: true,
|
||||
interactive: true,
|
||||
})
|
||||
|
||||
expect(findOutdatedGitHubActions).toHaveBeenCalledWith(expect.objectContaining({ dir: process.cwd() }))
|
||||
})
|
||||
|
||||
test('update --interactive looks for GitHub Actions updates when update.githubActions is true', async () => {
|
||||
await handler({
|
||||
...DEFAULT_OPTS,
|
||||
dir: process.cwd(),
|
||||
interactive: true,
|
||||
updateConfig: { githubActions: true },
|
||||
})
|
||||
|
||||
expect(findOutdatedGitHubActions).toHaveBeenCalledWith(expect.objectContaining({ dir: process.cwd() }))
|
||||
})
|
||||
Reference in new issue
Block a user