Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ commands:
parameters:
items:
type: string
default: go gradle python pipenv elixir composer gradle@9 maven sbt dotnet uv
default: go gradle python pipenv elixir composer gradle@9 maven dotnet uv
steps:
- run:
name: Installing Rosetta
Expand All @@ -460,6 +460,16 @@ commands:
- run:
name: Upgrade npm to satisfy package.json engine requirements (>=11.10)
command: npm install -g npm@^11.10
- restore_cache:
keys:
- acceptance-{{ checksum "scripts/install-sbt.sh" }}
- run:
name: Installing sbt 1.x
command: ./scripts/install-sbt.sh
- save_cache:
key: acceptance-{{ checksum "scripts/install-sbt.sh" }}
paths:
- ~/sbt

install-deps-macos-build:
parameters:
Expand Down Expand Up @@ -1323,7 +1333,6 @@ workflows:
- release-npm:
name: upload npm
context:
- team-hammerhead-common-deploy-tokens
- devex_cli_docker_hub
requires:
- upload github
Expand Down Expand Up @@ -1855,7 +1864,9 @@ jobs:
version: << pipeline.parameters.aws_version >>
- run:
name: Pre-Publishing
command: make release-pre
command: |
export NPM_ID_TOKEN=$(circleci run oidc get --claims '{"aud": "npm:registry.npmjs.org"}')
make release-pre
- failed-release-notification

npm-validation:
Expand Down Expand Up @@ -1988,7 +1999,9 @@ jobs:
deployment: stable
- run:
name: Publish to npm
command: ./release-scripts/upload-artifacts.sh npm
command: |
export NPM_ID_TOKEN=$(circleci run oidc get --claims '{"aud": "npm:registry.npmjs.org"}')
./release-scripts/upload-artifacts.sh npm
- failed-release-notification

trigger-building-distribution-channels:
Expand Down
4 changes: 2 additions & 2 deletions cliv2-private/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.26.4

require (
github.com/snyk/cli/cliv2 v0.0.0
github.com/snyk/remy-cli-extension v1.20.1
github.com/snyk/remy-cli-extension v1.23.0
)

require (
Expand Down Expand Up @@ -216,7 +216,7 @@ require (
github.com/snyk/container-cli v0.0.0-20260213211631-cd2b2cf8f3ea // indirect
github.com/snyk/dep-graph/go v0.0.0-20260127160647-c836da762c62 // indirect
github.com/snyk/error-catalog-golang-public v0.0.0-20260505112649-a5103d411663 // indirect
github.com/snyk/go-application-framework v0.6.2 // indirect
github.com/snyk/go-application-framework v0.6.5-0.20260706141127-9483f3b67782 // indirect
github.com/snyk/go-httpauth v0.0.0-20240307114523-1f5ea3f55c65 // indirect
github.com/snyk/policy-engine v1.1.4 // indirect
github.com/snyk/snyk-iac-capture v0.6.5 // indirect
Expand Down
8 changes: 4 additions & 4 deletions cliv2-private/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -585,14 +585,14 @@ github.com/snyk/dep-graph/go v0.0.0-20260127160647-c836da762c62 h1:kgZNQ5ztI4+n3
github.com/snyk/dep-graph/go v0.0.0-20260127160647-c836da762c62/go.mod h1:hTr91da/4ze2nk9q6ZW1BmfM2Z8rLUZSEZ3kK+6WGpc=
github.com/snyk/error-catalog-golang-public v0.0.0-20260505112649-a5103d411663 h1:j2ZPhi78wKIHTiL9EFTNVXMIbsk56FVF2d5Sy1ZwSYk=
github.com/snyk/error-catalog-golang-public v0.0.0-20260505112649-a5103d411663/go.mod h1:Ytttq7Pw4vOCu9NtRQaOeDU2dhBYUyNBe6kX4+nIIQ4=
github.com/snyk/go-application-framework v0.6.2 h1:grVccp5mzmctL2hpo9fTnonAEUeMqX+tGczXnECu3j4=
github.com/snyk/go-application-framework v0.6.2/go.mod h1:0YC7xCETnFTdz6rq8OQPL0aWekMLOkBQu1FE4/cReMA=
github.com/snyk/go-application-framework v0.6.5-0.20260706141127-9483f3b67782 h1:ErhPyGnqAYJeVAqB+tdvEYpdBdfXwDkTxHRmHLdeLqg=
github.com/snyk/go-application-framework v0.6.5-0.20260706141127-9483f3b67782/go.mod h1:0YC7xCETnFTdz6rq8OQPL0aWekMLOkBQu1FE4/cReMA=
github.com/snyk/go-httpauth v0.0.0-20240307114523-1f5ea3f55c65 h1:CEQuYv0Go6MEyRCD3YjLYM2u3Oxkx8GpCpFBd4rUTUk=
github.com/snyk/go-httpauth v0.0.0-20240307114523-1f5ea3f55c65/go.mod h1:88KbbvGYlmLgee4OcQ19yr0bNpXpOr2kciOthaSzCAg=
github.com/snyk/policy-engine v1.1.4 h1:0XpaMpl7ixSk4+dlpHYg2iKEBuv+5Ci+QIcbsmhktao=
github.com/snyk/policy-engine v1.1.4/go.mod h1:yAlMDZhzORiZcbJCW0GEk/nHkc4DBDKp8BRoiGTWkBE=
github.com/snyk/remy-cli-extension v1.20.1 h1:Y5h3oqbKghkkObRqwvF8qkX6OtmmKDAbh+OTW7oNppc=
github.com/snyk/remy-cli-extension v1.20.1/go.mod h1:qpL64pAGKDAbApnP8CLIAIOLPD6R+Ge6qA4m0L2auKo=
github.com/snyk/remy-cli-extension v1.23.0 h1:cjfoltDIsJlunC2Zsx9hPN8EuJAAPUCZFDJvyg6Qj90=
github.com/snyk/remy-cli-extension v1.23.0/go.mod h1:qpL64pAGKDAbApnP8CLIAIOLPD6R+Ge6qA4m0L2auKo=
github.com/snyk/snyk-iac-capture v0.6.5 h1:992DXCAJSN97KtUh8T5ndaWwd/6ZCal2bDkRXqM1u/E=
github.com/snyk/snyk-iac-capture v0.6.5/go.mod h1:e47i55EmM0F69ZxyFHC4sCi7vyaJW6DLoaamJJCzWGk=
github.com/snyk/snyk-ls v0.0.0-20260626083941-77c2abaeaaaa h1:qKLDBzWOoLLn06e69Cw7MLb6TtInLN+Y6IhD+oYVxdw=
Expand Down
2 changes: 1 addition & 1 deletion cliv2/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ require (
github.com/snyk/code-client-go v1.27.0
github.com/snyk/container-cli v0.0.0-20260213211631-cd2b2cf8f3ea
github.com/snyk/error-catalog-golang-public v0.0.0-20260505112649-a5103d411663
github.com/snyk/go-application-framework v0.6.2
github.com/snyk/go-application-framework v0.6.5-0.20260706141127-9483f3b67782
github.com/snyk/go-httpauth v0.0.0-20240307114523-1f5ea3f55c65
github.com/snyk/snyk-iac-capture v0.6.5
github.com/snyk/snyk-ls v0.0.0-20260626083941-77c2abaeaaaa
Expand Down
4 changes: 2 additions & 2 deletions cliv2/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -547,8 +547,8 @@ github.com/snyk/dep-graph/go v0.0.0-20260127160647-c836da762c62 h1:kgZNQ5ztI4+n3
github.com/snyk/dep-graph/go v0.0.0-20260127160647-c836da762c62/go.mod h1:hTr91da/4ze2nk9q6ZW1BmfM2Z8rLUZSEZ3kK+6WGpc=
github.com/snyk/error-catalog-golang-public v0.0.0-20260505112649-a5103d411663 h1:j2ZPhi78wKIHTiL9EFTNVXMIbsk56FVF2d5Sy1ZwSYk=
github.com/snyk/error-catalog-golang-public v0.0.0-20260505112649-a5103d411663/go.mod h1:Ytttq7Pw4vOCu9NtRQaOeDU2dhBYUyNBe6kX4+nIIQ4=
github.com/snyk/go-application-framework v0.6.2 h1:grVccp5mzmctL2hpo9fTnonAEUeMqX+tGczXnECu3j4=
github.com/snyk/go-application-framework v0.6.2/go.mod h1:0YC7xCETnFTdz6rq8OQPL0aWekMLOkBQu1FE4/cReMA=
github.com/snyk/go-application-framework v0.6.5-0.20260706141127-9483f3b67782 h1:ErhPyGnqAYJeVAqB+tdvEYpdBdfXwDkTxHRmHLdeLqg=
github.com/snyk/go-application-framework v0.6.5-0.20260706141127-9483f3b67782/go.mod h1:0YC7xCETnFTdz6rq8OQPL0aWekMLOkBQu1FE4/cReMA=
github.com/snyk/go-httpauth v0.0.0-20240307114523-1f5ea3f55c65 h1:CEQuYv0Go6MEyRCD3YjLYM2u3Oxkx8GpCpFBd4rUTUk=
github.com/snyk/go-httpauth v0.0.0-20240307114523-1f5ea3f55c65/go.mod h1:88KbbvGYlmLgee4OcQ19yr0bNpXpOr2kciOthaSzCAg=
github.com/snyk/policy-engine v1.1.4 h1:0XpaMpl7ixSk4+dlpHYg2iKEBuv+5Ci+QIcbsmhktao=
Expand Down
2 changes: 1 addition & 1 deletion cliv2/pkg/core/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ import (
"github.com/snyk/cli/cliv2/internal/cliv2"
"github.com/snyk/cli/cliv2/internal/constants"

cliv2utils "github.com/snyk/cli/cliv2/internal/utils"
persona "github.com/snyk/cli/cliv2/internal/persona"
cliv2utils "github.com/snyk/cli/cliv2/internal/utils"

localworkflows "github.com/snyk/go-application-framework/pkg/local_workflows"
"github.com/snyk/go-application-framework/pkg/local_workflows/config_utils"
Expand Down
2 changes: 0 additions & 2 deletions release-scripts/upload-artifacts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,11 @@ upload_npm() {

if [ "${DRY_RUN}" == true ]; then
echo "DRY RUN: uploading to npm..."
npm config set '//registry.npmjs.org/:_authToken' "${HAMMERHEAD_NPM_TOKEN}"
npm publish --dry-run ${npm_tag_arg} ./binary-releases/snyk-fix.tgz
npm publish --dry-run ${npm_tag_arg} ./binary-releases/snyk-protect.tgz
npm publish --dry-run ${npm_tag_arg} ./binary-releases/snyk.tgz
else
echo "Uploading to npm..."
npm config set '//registry.npmjs.org/:_authToken' "${HAMMERHEAD_NPM_TOKEN}"
npm publish ${npm_tag_arg} ./binary-releases/snyk-fix.tgz
npm publish ${npm_tag_arg} ./binary-releases/snyk-protect.tgz
npm publish ${npm_tag_arg} ./binary-releases/snyk.tgz
Expand Down
41 changes: 41 additions & 0 deletions scripts/install-sbt.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
# pinned sbt 1.x for acceptance tests; snyk-sbt-plugin does not support sbt 2.x
set -euo pipefail

SBT_VERSION="1.12.11"
SBT_SHA256="5f972a79d2a5bf8f29141a74c35e686bb0860a6b6ec677af892f94cf9b124645"
SBT_HOME="${SBT_HOME:-${HOME}/sbt}"

download() {
if command -v wget >/dev/null 2>&1; then
wget -qO "$2" "$1"
else
curl -fsSL -o "$2" "$1"
fi
}

if [ ! -x "${SBT_HOME}/bin/sbt" ] || [[ "$("${SBT_HOME}/bin/sbt" --version 2>&1 || true)" != *"${SBT_VERSION}"* ]]; then
echo "Installing sbt ${SBT_VERSION} to ${SBT_HOME}"
base="https://github.com/sbt/sbt/releases/download/v${SBT_VERSION}"
tarball="/tmp/sbt-${SBT_VERSION}.tgz"
download "${base}/sbt-${SBT_VERSION}.tgz" "${tarball}"
if command -v sha256sum >/dev/null 2>&1; then
actual=$(sha256sum "${tarball}" | awk '{print $1}')
else
actual=$(shasum -a 256 "${tarball}" | awk '{print $1}')
fi
if [ "${actual}" != "${SBT_SHA256}" ]; then
echo "ERROR: checksum verification failed for ${tarball}"
echo "Expected: ${SBT_SHA256}"
echo "Actual: ${actual}"
exit 1
fi
rm -rf "${SBT_HOME}"
tar xzf "${tarball}" -C "${HOME}"
fi

if [ -n "${BASH_ENV:-}" ]; then
echo "export PATH=\"${SBT_HOME}/bin:\$PATH\"" >> "$BASH_ENV"
fi
export PATH="${SBT_HOME}/bin:${PATH}"
sbt --version
64 changes: 64 additions & 0 deletions test/jest/acceptance/doctor.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { runSnykCLI } from '../util/runSnykCLI';

jest.setTimeout(1000 * 120);

describe('snyk doctor', () => {
const env = {
...process.env,
SNYK_DISABLE_ANALYTICS: '1',
};

describe('use doctor on the current system (live checks)', () => {
it('outputs a human readable report', async () => {
const { code, stdout } = await runSnykCLI('doctor --live', { env });

expect(code).toBe(0);
expect(stdout).toContain('Snyk Doctor Diagnostic Report');
});
});

describe('use doctor on the debug logs of another system', () => {
const fs = require('fs');
const os = require('os');
const path = require('path');

const sampleLog = [
'2026-06-10T13:10:38Z main - < response [0x1]: 401 Unauthorized',
'2026-06-10T13:10:38Z main - ------------ Summary ------------',
'2026-06-10T13:10:38Z main - ------------ Errors ------------',
'2026-06-10T13:10:38Z main - Authentication error (SNYK-0005)',
'2026-06-10T13:10:38Z main - Exit Code: 2',
].join('\n');

let logFile: string;
let tmpDir: string;

beforeEach(() => {
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'doctor-test-'));
logFile = path.join(tmpDir, 'debug.log');
fs.writeFileSync(logFile, sampleLog);
});

afterEach(() => {
fs.rmSync(tmpDir, { recursive: true, force: true });
});

it('analyzes the debug log and reports findings', async () => {
const { code, stdout } = await runSnykCLI(`doctor --input=${logFile}`, {
env,
});

expect(code).toBe(0);
expect(stdout).toContain('Snyk Doctor Diagnostic Report');
});

it('--input with non-existent file', async () => {
const { code } = await runSnykCLI(
'doctor --input=/tmp/does-not-exist-snyk-doctor-test.log',
{ env },
);

expect(code).not.toBe(0);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,34 @@
* Starter corpus. Expand per resolveDepgraphs-rollout-plan.md.
*/

import { fakeServer } from '../../../acceptance/fake-server';
import {
fakeServer,
getFirstIPv4Address,
} from '../../../acceptance/fake-server';
import { createProjectFromWorkspace } from '../../util/createProject';
import { getServerPort } from '../../util/getServerPort';
import { getAvailableServerPort } from '../../util/getServerPort';
import { assertEquivalent, runBothFlows } from './equivalenceHelpers';

jest.setTimeout(1000 * 60 * 3);
jest.setTimeout(1000 * 60 * 5);

describe('snyk test — unified test API equivalence (FF off vs on)', () => {
let server;
let env: Record<string, string>;

beforeAll((done) => {
const port = getServerPort(process);
beforeAll(async () => {
const port = await getAvailableServerPort(process);
const baseApi = '/v1';
const fakeServerIp = getFirstIPv4Address();
env = {
...process.env,
SNYK_API: 'http://localhost:' + port + baseApi,
SNYK_HOST: 'http://localhost:' + port,
SNYK_API: `http://${fakeServerIp}:${port}${baseApi}`,
SNYK_HOST: `http://${fakeServerIp}:${port}`,
SNYK_TOKEN: '123456789',
SNYK_DISABLE_ANALYTICS: '1',
SNYK_HTTP_PROTOCOL_UPGRADE: '0',
};
server = fakeServer(baseApi, env.SNYK_TOKEN);
server.listen(port, () => done());
await server.listenPromise(port);
});

afterAll((done) => {
Expand Down
2 changes: 2 additions & 0 deletions test/jest/util/runCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ const runCommand = (
): Promise<RunCommandResult> => {
return new Promise((resolve, reject) => {
const child = spawn(command, args, options);
// default pipe stdin blocks commands that read until EOF (e.g. doctor)
child.stdin?.end();
const stdout: Buffer[] = [];
const stderr: Buffer[] = [];

Expand Down