Skip to content

Add parameter validation and integration tests with CI integration #509

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 36 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
05d2c79
Adding integration tests
Aug 8, 2025
82d8576
add test step to ci pipeline
Aug 8, 2025
496c300
adding steps to upload test results as well
Aug 8, 2025
2ef3ca3
removing server side tests as these not E2E tests.
Aug 9, 2025
751b9d0
cleaning up
Aug 9, 2025
ba7524e
Adding additional tests for scenarios needing AZDO server calls
Aug 9, 2025
d16c491
removing unnecessary flie
Aug 9, 2025
479d61d
checkin intermiddiate changes
Aug 9, 2025
18f6c19
intermiddiate changes
Aug 9, 2025
92d1fd9
more intermittiate changes
Aug 9, 2025
f2d99d9
updaing guids
Aug 9, 2025
a12ad5f
cleanup
Aug 9, 2025
eeaad40
cleaned up packages.json files
Aug 9, 2025
6e216ed
adding logging option
Aug 9, 2025
0d1e5fa
cleaning up the mock server package
Aug 9, 2025
79646ce
making tests more reliable by making use of precreated files
Aug 9, 2025
e5bf8fc
simplifying test structure
Aug 9, 2025
d1378e7
simplifyng extension tests
Aug 9, 2025
fda5735
removing unneccesary assertions
Aug 9, 2025
cea246d
intermiddiate progress for fixing the assertions
Aug 10, 2025
a4ca912
fixed all the test with proper checks
Aug 10, 2025
2b4d993
removing md file that is not needed
Aug 10, 2025
f55fb28
fixing other test with debug logging and adding debug log variables i…
Aug 10, 2025
af33987
removing secrets
Aug 10, 2025
b74ce9e
trying to fix test failure
Aug 10, 2025
b77b242
few fixes
Aug 10, 2025
ecbc9e0
updating version
Aug 10, 2025
1fc1ef5
adding temo pipeline to test this on all os and different node versions
Aug 10, 2025
6cf4957
fixing minor error
Aug 10, 2025
57b587f
removing variable group
Aug 10, 2025
a65aae8
updating yml
Aug 10, 2025
2df1070
yml
Aug 10, 2025
9870ceb
updaing scripts to be cross platform
Aug 10, 2025
b9e8229
updating script to remove node 10
Aug 10, 2025
2b3fe38
removing unstable tests and corner cases
Aug 10, 2025
87ed3d7
cleanup
Aug 10, 2025
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
8 changes: 8 additions & 0 deletions .azure-pipelines/azure-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ trigger:

variables:
- group: npm-tokens
# Debug/verbose output variables for CLI and mock server
- name: DEBUG_CLI_OUTPUT
value: 'false'
- name: DEBUG_MOCKSERVER_OUTPUT
value: 'false'
# Enable verbose tracing for TFX CLI (if supported)
- name: TFX_TRACE
value: ''
resources:
repositories:
- repository: 1ESPipelineTemplates
Expand Down
23 changes: 23 additions & 0 deletions .azure-pipelines/common-steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,34 @@ steps:
- script: npm i -g [email protected] --force
displayName: Use npm version 8.19.4

- bash: |
cd packages/tfs-mock-server
npm ci
npm run build
displayName: Install and Build Mock Server

- bash: |
npm ci
npm run build
displayName: Build TFX CLI

- bash: |
export DEBUG_CLI_OUTPUT="$DEBUG_CLI_OUTPUT"
export DEBUG_MOCKSERVER_OUTPUT="$DEBUG_MOCKSERVER_OUTPUT"
export TFX_TRACE="$TFX_TRACE"
npm run test:ci
displayName: Run Tests
continueOnError: true

- task: PublishTestResults@2
displayName: Publish Test Results
condition: succeededOrFailed()
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: 'test-results.xml'
failTaskOnFailedTests: true
testRunTitle: 'TFX CLI Tests'

# Generate a pipeline artifact so we can publish the package manually if there are issues with automation
- bash: |
npm pack
Expand Down
105 changes: 105 additions & 0 deletions .azure-pipelines/multi-os-matrix.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Multi-OS/Node matrix pipeline for tfs-cli
trigger: none

variables:
- name: DEBUG_CLI_OUTPUT
value: 'false'
- name: DEBUG_MOCKSERVER_OUTPUT
value: 'false'
- name: TFX_TRACE
value: ''

stages:
- stage: matrix_test
displayName: Matrix Test
jobs:
- job: matrix
displayName: Run tests on all Node/OS combinations
strategy:
matrix:
windows_node16:
imageName: 'windows-2022'
nodeVersion: '16.x'
windows_node20:
imageName: 'windows-2022'
nodeVersion: '20.x'
ubuntu_node16:
imageName: 'ubuntu-24.04'
nodeVersion: '16.x'
ubuntu_node20:
imageName: 'ubuntu-24.04'
nodeVersion: '20.x'
macos_node16:
imageName: 'macos-14'
nodeVersion: '16.x'
macos_node20:
imageName: 'macos-14'
nodeVersion: '20.x'
pool:
vmImage: $(imageName)
steps:
- checkout: self
clean: true
- task: UseNode@1
displayName: Use Node $(nodeVersion)
inputs:
version: '$(nodeVersion)'
- task: NpmAuthenticate@0
inputs:
workingFile: .npmrc
- script: |
if [[ "$(nodeVersion)" =~ ^(10|12|14|16|18) ]]; then
npm i -g [email protected] --force
npm --version
else
npm i -g npm@10 --force
npm --version
fi
displayName: Use compatible npm version for Node (Linux/macOS)
condition: ne( variables['Agent.OS'], 'Windows_NT' )
- script: |
if "%nodeVersion%" == "16.x" (
npm i -g [email protected] --force
npm --version
) else if "%nodeVersion%" == "20.x" (
npm i -g npm@10 --force
npm --version
) else (
npm --version
)
displayName: Use compatible npm version for Node (Windows)
condition: eq( variables['Agent.OS'], 'Windows_NT' )
- script: npm ci
displayName: npm ci
- script: npm run build
displayName: Build TFX CLI
- script: |
export DEBUG_CLI_OUTPUT="$DEBUG_CLI_OUTPUT"
export DEBUG_MOCKSERVER_OUTPUT="$DEBUG_MOCKSERVER_OUTPUT"
export TFX_TRACE="$TFX_TRACE"
npm run test:ci
displayName: Run Tests (Linux/macOS)
condition: ne( variables['Agent.OS'], 'Windows_NT' )
env:
DEBUG_CLI_OUTPUT: $(DEBUG_CLI_OUTPUT)
DEBUG_MOCKSERVER_OUTPUT: $(DEBUG_MOCKSERVER_OUTPUT)
TFX_TRACE: $(TFX_TRACE)
- script: |
set DEBUG_CLI_OUTPUT=%DEBUG_CLI_OUTPUT%
set DEBUG_MOCKSERVER_OUTPUT=%DEBUG_MOCKSERVER_OUTPUT%
set TFX_TRACE=%TFX_TRACE%
npm run test:ci
displayName: Run Tests (Windows)
condition: eq( variables['Agent.OS'], 'Windows_NT' )
env:
DEBUG_CLI_OUTPUT: $(DEBUG_CLI_OUTPUT)
DEBUG_MOCKSERVER_OUTPUT: $(DEBUG_MOCKSERVER_OUTPUT)
TFX_TRACE: $(TFX_TRACE)
- task: PublishTestResults@2
displayName: Publish Test Results
condition: succeededOrFailed()
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: 'test-results.xml'
failTaskOnFailedTests: true
testRunTitle: 'TFX CLI Tests (Matrix)'
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
# Build and Packaging
_build

# Tests
_tests
test-results.xml
tfs-cli.code-workspace

# Mock server package build output
packages/tfs-mock-server/lib/
packages/tfs-mock-server/node_modules/

# Logs
logs
*.log
Expand Down
5 changes: 5 additions & 0 deletions .mocharc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"slow": 2000,
"timeout": 60000,
"reporter": "spec"
}
160 changes: 153 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,27 +106,173 @@ queue time : Fri Aug 21 2015 15:07:49 GMT-0400 (Eastern Daylight Time)

If you used `--save` to set a default value for an option, you may need to override it by explicitly providing a different value. You can clear any saved settings by running `tfx reset`.

### Troubleshooting

To see detailed tracing output, set a value for the `TFX_TRACE` environment variable and then run commands. This may provide clues to the issue and can be helpful when logging an issue.
### Troubleshooting & Verbose Logging

### Troubleshooting on Linux/OSX
#### CLI Trace Output
To see detailed tracing output from the CLI, set the `TFX_TRACE` environment variable and then run commands. This may provide clues to the issue and can be helpful when logging an issue.

**Linux/OSX:**
```bash
export TFX_TRACE=1
```
**Windows:**
```bash
set TFX_TRACE=1
```
**PowerShell:**
```bash
$env:TFX_TRACE=1
```

### Troubleshooting on Windows
#### Debug Output from Tests
To enable detailed debug output for all CLI commands executed during tests, set the `DEBUG_CLI_OUTPUT` environment variable to `true`:

**Linux/OSX:**
```bash
set TFX_TRACE=1
export DEBUG_CLI_OUTPUT=true
```
**Windows:**
```bash
set DEBUG_CLI_OUTPUT=true
```
**PowerShell:**
```bash
$env:DEBUG_CLI_OUTPUT='true'
```
This will print detailed command execution logs for every CLI call made by the test suite.

#### PowerShell
#### Mock Server Verbose Logging
To enable verbose logging for the integrated mock server (used in server integration tests), set the `DEBUG_MOCKSERVER_OUTPUT` environment variable to `true`:

**Linux/OSX:**
```bash
$env:TFX_TRACE=1
export DEBUG_MOCKSERVER_OUTPUT=true
```
**Windows:**
```bash
set DEBUG_MOCKSERVER_OUTPUT=true
```
**PowerShell:**
```bash
$env:DEBUG_MOCKSERVER_OUTPUT='true'
```
This will print detailed request/response and lifecycle logs from the mock server during test runs.

All three variables (`TFX_TRACE`, `DEBUG_CLI_OUTPUT`, `DEBUG_MOCKSERVER_OUTPUT`) are also available as pipeline variables in the Azure DevOps pipeline and default to `false`.

## Development

### Building from Source

To build the project from source:

1. **Install dependencies:**
```bash
npm install
```

2. **Build the main project:**
```bash
npm run build
```

This compiles the TypeScript source files in the `app/` directory to JavaScript in the `_build/` directory using the TypeScript compiler and copies necessary files.

3. **Clean build artifacts (optional):**
```bash
npm run clean
```

### Testing

The project includes comprehensive tests, including server integration tests with an integrated mock server. To run them:

1. **Build the project first (required):**
```bash
npm run build
```

2. **Run all tests:**
```bash
npm test
```

This builds the test files and runs all test suites.

3. **Run specific test suites:**
```bash
npm run test:build-commands
npm run test:extension-commands
npm run test:commandline
npm run test:server-integration
```

4. **Run tests with CI reporter:**
```bash
npm run test:ci
```

**Note:** The mock server is now integrated as part of the test suite in the `tests/mock-server/` directory and is automatically compiled when running tests. No separate build step is required for the mock server.

### Enabling Mock Server Verbose Logging

For debugging server integration tests, you can enable verbose logging for the mock server to see detailed request/response information. This requires modifying the test files temporarily:

1. **Locate the test file** you want to debug (e.g., `tests/server-integration-login.ts`)

2. **Find the `createMockServer` call** in the `before()` hook:
```typescript
// Current call
mockServer = await createMockServer({ port: 8084 });

// Add verbose option
mockServer = await createMockServer({ port: 8084, verbose: true });
```

3. **Run the specific test** to see verbose output:
```bash
npm run test:server-integration-login
```

4. **Verbose output will include:**
- HTTP method and path for each request
- Authorization headers (with tokens obscured for security)
- Mock server lifecycle events
- Request processing details

**Example verbose output:**
```
Mock DevOps server listening on http://localhost:8084
Mock Server: GET /_apis/connectionData - Authorization: Basic tes***ass
Mock Server: POST /_apis/build/builds - Authorization: Bearer abc***xyz
Mock DevOps server closed
```

**Important:** Remember to remove the `verbose: true` option before committing your changes, as it's intended for debugging purposes only.

### Testing Your Changes Locally

After building, you can test your changes locally in several ways:

1. **Using Node.js directly:**
```bash
node _build/tfx-cli.js
node _build/tfx-cli.js --help
```

2. **Using npm link for global installation:**
```bash
npm link
tfx
```

**To remove the link when done testing:**
```bash
npm unlink -g tfx-cli
```

The built executable is located at `_build/tfx-cli.js` and serves as the main entry point for the CLI.

## Contributing

Expand Down
8 changes: 4 additions & 4 deletions app/exec/extension/_lib/vsix-manifest-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,13 +258,13 @@ export class VsixManifestBuilder extends ManifestBuilder {
});
break;
case "details":
if (_.isObject(value) && value.path) {
if (_.isObject(value) && (value as any).path) {
let fileDecl: FileDeclaration = {
path: value.path,
path: (value as any).path,
addressable: true,
auto: true,
assetType: "Microsoft.VisualStudio.Services.Content.Details",
contentType: value.contentType,
contentType: (value as any).contentType,
};
this.addFile(fileDecl, true);
}
Expand Down Expand Up @@ -304,7 +304,7 @@ export class VsixManifestBuilder extends ManifestBuilder {
break;
case "repository":
if (_.isObject(value)) {
const { type, url, uri } = value;
const { type, url, uri } = value as any;
if (!type) {
throw new Error("Repository must have a 'type' property.");
}
Expand Down
2 changes: 1 addition & 1 deletion app/exec/extension/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import jsonInPlace from "json-in-place";
import { promisify } from "util";
import { TfCommand } from "../../lib/tfcommand";
import * as args from "../../lib/arguments";
import * as colors from "colors";
import colors = require("colors");
import * as extBase from "./default";
import * as fs from "fs";
import * as http from "https";
Expand Down
Loading