diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c7ae7a0..4a85fd9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,6 +20,45 @@ We use GitHub to host code, to track issues and feature requests, as well as acc 4. Push to the branch (`git push origin feature/amazing-feature`) 5. Open a Pull Request +## Development Practices + +This project follows Test-Driven Development practices. Each new feature should: + +1. Begin with a failing test +2. Implement the minimal code to make the test pass +3. Refactor while keeping tests green + +## Testing + +### Unit Tests + +Run unit tests with: + +```bash +npm run test:unit +``` + +### Integration Tests + +Integration tests require a connection to a real Azure DevOps instance. To run them: + +1. Ensure your `.env` file is configured with valid Azure DevOps credentials: + + ``` + AZURE_DEVOPS_ORG_URL=https://dev.azure.com/your-organization + AZURE_DEVOPS_PAT=your-personal-access-token + AZURE_DEVOPS_DEFAULT_PROJECT=your-project-name + ``` + +2. Run the integration tests: + ```bash + npm run test:integration + ``` + +### CI Environment + +For running tests in CI environments (like GitHub Actions), see [CI Environment Setup](docs/ci-setup.md) for instructions on configuring secrets. + ## Commit Message Guidelines We follow the [Conventional Commits](https://www.conventionalcommits.org/) specification for our commit messages. This leads to more readable messages that are easy to follow when looking through the project history and enables automatic versioning and changelog generation. @@ -81,6 +120,15 @@ npm run commit This will start an interactive prompt that will help you generate a properly formatted commit message. +## Release Process + +This project uses [Conventional Commits](https://www.conventionalcommits.org/) to automate versioning and changelog generation. When contributing, please follow the commit message convention. + +To create a commit with the correct format, use: +```bash +npm run commit +``` + ## Automated Release Workflow Our project uses an automated release workflow that leverages Conventional Commits to manage semantic versioning, generate changelogs, and create GitHub Releases. diff --git a/README.md b/README.md index 9da19c5..dc71076 100644 --- a/README.md +++ b/README.md @@ -40,65 +40,55 @@ The server is structured around the Model Context Protocol (MCP) for communicati - Azure Identity credentials, or - Azure CLI login -### Installation +### Running with NPX -1. Clone the repository: +### Usage with Claude Desktop/Cursor AI - ``` - git clone https://github.com/your-username/azure-devops-mcp.git - cd azure-devops-mcp - ``` +To integrate with Claude Desktop or Cursor AI, add one of the following configurations to your configuration file. -2. Install dependencies: - ``` - npm install - ``` +#### Azure Identity Authentication -3. Set up your environment: - - Option A: Using the automated setup script (recommended): - - ``` - chmod +x setup_env.sh - ./setup_env.sh - ``` - - This script will: - - - Check for and install the Azure CLI DevOps extension if needed - - Let you select from your available Azure DevOps organizations - - Optionally set a default project - - Create a Personal Access Token with the required permissions - - Generate your `.env` file with the correct settings - - Option B: Manual setup: - - ``` - cp .env.example .env - ``` - - Then edit the `.env` file with your Azure DevOps credentials (see Authentication section below). - -### Running the Server - -Build the TypeScript files: +Be sure you are logged in to Azure CLI with `az login` then add the following: -``` -npm run build +```json +{ + "mcpServers": { + "azureDevOps": { + "command": "npx", + "args": ["-y", "@tiberriver256/mcp-server-azure-devops"], + "env": { + "AZURE_DEVOPS_ORG_URL": "https://dev.azure.com/your-organization", + "AZURE_DEVOPS_AUTH_METHOD": "azure-identity", + "AZURE_DEVOPS_DEFAULT_PROJECT": "your-project-name" + } + } + } +} ``` -Start the server: -``` -npm start +#### Personal Access Token (PAT) Authentication + +```json +{ + "mcpServers": { + "azureDevOps": { + "command": "npx", + "args": ["-y", "@tiberriver256/mcp-server-azure-devops"], + "env": { + "AZURE_DEVOPS_ORG_URL": "https://dev.azure.com/your-organization", + "AZURE_DEVOPS_AUTH_METHOD": "pat", + "AZURE_DEVOPS_PAT": "", + "AZURE_DEVOPS_DEFAULT_PROJECT": "your-project-name" + } + } + } +} ``` -For development with hot reloading: +For detailed configuration instructions and more authentication options, see the [Authentication Guide](docs/authentication.md). -``` -npm run dev -``` ## Authentication Methods @@ -118,20 +108,18 @@ For a complete list of environment variables and their descriptions, see the [Au Key environment variables include: -| Variable | Description | Required | Default | -| ------------------------------ | --------------------------------------------------------------- | ------------------ | ------------------ | +| Variable | Description | Required | Default | +| ------------------------------ | ---------------------------------------------------------------------------------- | ------------------ | ------------------ | | `AZURE_DEVOPS_AUTH_METHOD` | Authentication method (`pat`, `azure-identity`, or `azure-cli`) - case-insensitive | No | `azure-identity` | -| `AZURE_DEVOPS_ORG` | Azure DevOps organization name | No | Extracted from URL | -| `AZURE_DEVOPS_ORG_URL` | Full URL to your Azure DevOps organization | Yes | - | -| `AZURE_DEVOPS_PAT` | Personal Access Token (for PAT auth) | Only with PAT auth | - | -| `AZURE_DEVOPS_DEFAULT_PROJECT` | Default project if none specified | No | - | -| `AZURE_DEVOPS_API_VERSION` | API version to use | No | Latest | -| `AZURE_AD_TENANT_ID` | Azure AD tenant ID (for AAD auth) | Only with AAD auth | - | -| `AZURE_AD_CLIENT_ID` | Azure AD application ID (for AAD auth) | Only with AAD auth | - | -| `AZURE_AD_CLIENT_SECRET` | Azure AD client secret (for AAD auth) | Only with AAD auth | - | -| `PORT` | Server port | No | 3000 | -| `HOST` | Server host | No | localhost | -| `LOG_LEVEL` | Logging level (debug, info, warn, error) | No | info | +| `AZURE_DEVOPS_ORG` | Azure DevOps organization name | No | Extracted from URL | +| `AZURE_DEVOPS_ORG_URL` | Full URL to your Azure DevOps organization | Yes | - | +| `AZURE_DEVOPS_PAT` | Personal Access Token (for PAT auth) | Only with PAT auth | - | +| `AZURE_DEVOPS_DEFAULT_PROJECT` | Default project if none specified | No | - | +| `AZURE_DEVOPS_API_VERSION` | API version to use | No | Latest | +| `AZURE_AD_TENANT_ID` | Azure AD tenant ID (for AAD auth) | Only with AAD auth | - | +| `AZURE_AD_CLIENT_ID` | Azure AD application ID (for AAD auth) | Only with AAD auth | - | +| `AZURE_AD_CLIENT_SECRET` | Azure AD client secret (for AAD auth) | Only with AAD auth | - | +| `LOG_LEVEL` | Logging level (debug, info, warn, error) | No | info | ## Troubleshooting Authentication @@ -177,58 +165,10 @@ For repository-specific tool documentation, see the [Repositories Tools Guide](d - `get_work_item`: Retrieve a work item by ID - `create_work_item`: Create a new work item -## Testing - -### Unit Tests - -Run unit tests with: - -```bash -npm run test:unit -``` - -### Integration Tests - -Integration tests require a connection to a real Azure DevOps instance. To run them: - -1. Ensure your `.env` file is configured with valid Azure DevOps credentials: - - ``` - AZURE_DEVOPS_ORG_URL=https://dev.azure.com/your-organization - AZURE_DEVOPS_PAT=your-personal-access-token - AZURE_DEVOPS_DEFAULT_PROJECT=your-project-name - ``` - -2. Run the integration tests: - ```bash - npm run test:integration - ``` - -### CI Environment - -For running tests in CI environments (like GitHub Actions), see [CI Environment Setup](docs/ci-setup.md) for instructions on configuring secrets. - -## Development - -This project follows Test-Driven Development practices. Each new feature should: - -1. Begin with a failing test -2. Implement the minimal code to make the test pass -3. Refactor while keeping tests green - -## Release Process - -This project uses [Conventional Commits](https://www.conventionalcommits.org/) to automate versioning and changelog generation. When contributing, please follow the commit message convention. +## Contributing -To create a commit with the correct format, use: -```bash -npm run commit -``` +Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines. ## License MIT - -## Contributing - -Contributions are welcome! Please feel free to submit a Pull Request. diff --git a/project-management/startup.xml b/project-management/startup.xml index 9e15874..869ca5c 100644 --- a/project-management/startup.xml +++ b/project-management/startup.xml @@ -1,6 +1,7 @@ If an ANY point you get stuck, review troubleshooter.xml to help you troubleshoot the problem. All new code creation should ALWAYS follow tdd-cycle.xml + Tasks in todo.md are sorted in order of priority - ALWAYS pick the task from the top of the list. Read the dream team documentation at project-management/planning/the-dream-team.md to understand the team structure and roles Read all files in the project-management/planning directory to understand the project architecture, features, and structure @@ -12,7 +13,7 @@ - Available tools and integrations Examine the current task list by viewing the project-management/task-management/ files todo.md and doing.md - If there is a task in doing.md move directly into TaskWorkflow. If not take the next task from todo.md and move it to doing.md, removing it from todo.md. After moving the task you should extend it with a phase property to be used in TaskWorkflow and a section for notes and sub-tasks. + If there is a task in doing.md move directly into TaskWorkflow. If not take the FIRST task from the top of todo.md and move it to doing.md, removing it from todo.md. Remember that tasks are sorted by priority with most important at the top. After moving the task you should extend it with a phase property to be used in TaskWorkflow and a section for notes and sub-tasks. Create a new branch for the current task, branching from the latest main branch. Use a descriptive name for the branch, related to the task, by running ./create_branch.sh <branch_name>. Read tdd-cycle.xml to understand the TDD cycle. Start the research phase of TaskWorkflow. @@ -54,5 +55,6 @@ Use the GitHub CLI (gh) for any GitHub-related tasks Use Puppeteer if web browsing is required If any task is unclear, stop and ask for clarification before proceeding + Always take tasks from the top of todo.md as they are sorted in priority order diff --git a/project-management/task-management/doing.md b/project-management/task-management/doing.md index b322898..e69de29 100644 --- a/project-management/task-management/doing.md +++ b/project-management/task-management/doing.md @@ -1,231 +0,0 @@ -**AI Agent Task Prompt: Implement Automated Release Workflow** - -**Persona:** Act as an expert DevOps Engineer specializing in CI/CD automation and release management. - -**Context:** This repository, `azure-devops-mcp`, needs a fully automated release workflow. This workflow will leverage Conventional Commits to manage semantic versioning, generate changelogs, and create GitHub Releases. This automation will improve release consistency, reduce manual effort, and provide clear release history. The designated npm package name for this repository is **`@tiberriver256/mcp-server-azure-devops`**. - -**Overall Goal:** Configure the repository to automatically handle versioning, changelog generation, and GitHub releases based on commit message conventions. - -**Instructions:** Follow these steps precisely. Use the provided commands exactly unless an error occurs. Verify each step's success before proceeding. Report any errors or ambiguities immediately. Use checkboxes `[ ]` to track progress, replacing `[ ]` with `[x]` upon successful completion of each sub-task. - ---- - -**### Phase 1: Setup Conventional Commits Standards & Enforcement (Local)** -* **Context:** This phase installs and configures tools to ensure all future commit messages adhere to the Conventional Commits standard, which is foundational for automation. - -* **Task 1: Install Required Tooling** - * [x] **Sub-task 1.1:** Navigate to the project's root directory. - * [x] **Sub-task 1.2:** Execute the following command to install necessary development dependencies: - ```bash - npm install --save-dev @commitlint/cli @commitlint/config-conventional husky commitizen cz-conventional-changelog standard-version - ``` - * [x] **Sub-task 1.3:** Verify that the command completed successfully and the listed packages are added to `devDependencies` in `package.json`. - -* **Task 2: Configure `commitlint`** - * [x] **Sub-task 2.1:** Create a new file named `commitlint.config.js` in the project root directory. - * [x] **Sub-task 2.2:** Add the exact following content to `commitlint.config.js`: - ```javascript - // commitlint.config.js - module.exports = { - extends: ['@commitlint/config-conventional'], - }; - ``` * [x] **Sub-task 2.3:** Verify the file `commitlint.config.js` exists and contains the correct content. - -* **Task 3: Configure `husky` for Commit Message Linting** - * [x] **Sub-task 3.1:** Confirm the `prepare` script in `package.json` includes `husky install`. (It should already be present based on prior setup). - * [x] **Sub-task 3.2:** Confirm the `.husky/` directory exists at the project root. If not, execute `npx husky install`. - * [x] **Sub-task 3.3:** Add the `commit-msg` Git hook by executing the following command: - ```bash - npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"' - ``` - * [x] **Sub-task 3.4:** Verify the file `.husky/commit-msg` exists and its content matches the command string `'npx --no -- commitlint --edit "$1"'`. - -* **Task 4: Configure `commitizen` for Guided Commits** - * [x] **Sub-task 4.1:** Open `package.json`. - * [x] **Sub-task 4.2:** Add the following `config` block at the top level of the JSON structure (if it doesn't exist, create it): - ```json - // package.json - { - // ... other package.json content - "config": { - "commitizen": { - "path": "./node_modules/cz-conventional-changelog" - } - } - // ... other package.json content - } - ``` - * [x] **Sub-task 4.3:** Add the following script to the `scripts` object within `package.json`: - ```json - // package.json -> scripts - "commit": "cz" - ``` - * [x] **Sub-task 4.4:** Verify both additions in `package.json` are syntactically correct. - -* **Task 5: Verify Local Commit Enforcement and Guidance** - * [x] **Sub-task 5.1:** Create a temporary file (e.g., `touch temp_test.txt`) and stage it (`git add temp_test.txt`). - * [x] **Sub-task 5.2:** Attempt an invalid commit: `git commit -m "test setup"`. **Verify that the command fails** and output indicates a commitlint error. - * [x] **Sub-task 5.3:** Attempt a valid commit: `git commit -m "chore: test commitlint setup"`. **Verify that the command succeeds**. - * [x] **Sub-task 5.4:** Reset the successful commit: `git reset --soft HEAD~1`. - * [x] **Sub-task 5.5:** Clean up the temporary file: `git rm --cached temp_test.txt` and `rm temp_test.txt`. - * [x] **Sub-task 5.6:** Execute `npm run commit`. **Verify that an interactive prompt appears**, asking questions to build a conventional commit message. Exit the prompt without completing the commit (e.g., using Ctrl+C). - -* **Task 1.1**: Fix auth method case-sensitivity issue - * **Role**: Full-Stack Developer - * **Phase**: Completion - * **Description**: Make the `AZURE_DEVOPS_AUTH_METHOD` parameter case-insensitive - - ### Notes - - Currently, the auth method parameter is case-sensitive, causing issues when users enter values with different casing - - Need to research how the auth method is currently implemented - - Need to modify the validation/parsing logic to handle case variations - - Implemented a normalizeAuthMethod function that compares the auth method in a case-insensitive way - - Added comprehensive unit tests to verify case-insensitive behavior - - Updated documentation to clarify that the parameter is case-insensitive - - ### Sub-tasks - - [x] Research current implementation of auth method validation - - [x] Design approach for handling case-insensitive comparison - - [x] Implement the fix with proper error handling - - [x] Add tests to verify the fix works with different case variations - - [x] Update documentation to clarify that the parameter is now case-insensitive - ---- - -**### Phase 2: Setup Release Automation (`standard-version`)** -* **Context:** This phase configures the tool (`standard-version`) that will read conventional commits, determine the next semantic version, update the package version, and generate the changelog file. - -* **Task 6: Update `package.json` with the Correct Package Name** - * [x] **Sub-task 6.1:** Open `package.json`. - * [x] **Sub-task 6.2:** Modify the `name` field to exactly match: `@tiberriver256/mcp-server-azure-devops`. - * [x] **Sub-task 6.3:** Verify the change is saved correctly. - -* **Task 7: Add `standard-version` Release Scripts to `package.json`** - * [x] **Sub-task 7.1:** Open `package.json`. - * [x] **Sub-task 7.2:** Add the following scripts to the `scripts` object: - ```json - // package.json -> scripts - "release": "standard-version", - "release:minor": "standard-version --release-as minor", - "release:patch": "standard-version --release-as patch", - "release:major": "standard-version --release-as major", - "release:dryrun": "standard-version --dry-run" - ``` - * [x] **Sub-task 7.3:** Verify the additions are saved correctly. - -* **Task 8: Perform Initial Dry Run Verification** - * [x] **Sub-task 8.1:** Ensure there is at least one commit on your current branch with a conventional commit type (`feat:`, `fix:`, `chore:`, etc.). If unsure, create a simple `chore:` commit for testing purposes (e.g., update a comment in a file, commit with `git commit -m "chore: prepare for release dry-run"`). - * [x] **Sub-task 8.2:** Execute `npm run release:dryrun` in the terminal. - * [x] **Sub-task 8.3:** **Analyze the output:** - * Confirm it indicates the commits being processed. - * Confirm it suggests the correct next semantic version (e.g., `1.0.0` for the first release, or an appropriate bump based on commit types). - * Confirm it displays the content that *would* be added to `CHANGELOG.md`. - * Confirm it indicates that no actual changes were made to files (`--dry-run` mode). - * [x] **Sub-task 8.4:** Report any errors or unexpected output from the dry run. - ---- - -**### Phase 3: Integrate into CI/CD (GitHub Actions)** -* **Context:** This phase automates the release process using GitHub Actions. It configures a workflow that runs `standard-version`, pushes the version bump and changelog commit/tag, and creates a GitHub Release entry. - -* **Task 9: Create the Release Workflow File** - * [x] **Sub-task 9.1:** Create a directory path `.github/workflows/` if it doesn't exist. - * [x] **Sub-task 9.2:** Create a new file named `release.yml` inside `.github/workflows/`. - -* **Task 10: Define Workflow Trigger and Permissions** - * [x] **Sub-task 10.1:** Add the following content to `release.yml` to define the trigger and permissions: - ```yaml - name: Release Automation - - on: - workflow_dispatch: # Allows manual triggering for testing - - permissions: - contents: write # Allows pushing commits/tags and creating releases - ``` - -* **Task 11: Implement Workflow Steps for Release** - * [x] **Sub-task 11.1:** Add a job named `release` that runs on `ubuntu-latest`. - ```yaml - jobs: - release: - runs-on: ubuntu-latest - steps: - ``` - * [x] **Sub-task 11.2:** Add the Checkout step, ensuring `fetch-depth: 0`. - ```yaml - - name: Checkout code - uses: actions/checkout@v3 - with: - fetch-depth: 0 # Fetch all history for standard-version - token: ${{ secrets.GITHUB_TOKEN }} - ``` - * [x] **Sub-task 11.3:** Add the Setup Node.js step. - ```yaml - - name: Setup Node.js - uses: actions/setup-node@v3 - with: - node-version: 'lts/*' # Use the project's LTS Node version - ``` - * [x] **Sub-task 11.4:** Add the Install Dependencies step. - ```yaml - - name: Install Dependencies - run: npm ci - ``` - * [x] **Sub-task 11.5:** Add the Configure Git step. - ```yaml - - name: Configure Git - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - ``` - * [x] **Sub-task 11.6:** Add the Run `standard-version` step. Decide if `--first-release` is needed based on whether tags already exist. Use a dynamic approach if possible, otherwise, you might need to manually run the first release or adjust this step. For now, use a standard release command. - ```yaml - - name: Create Release Bump and Changelog - run: npm run release -- --commit-all # standard-version determines version based on commits - # Add --first-release if this is the absolute first tag/release - ``` - * [x] **Sub-task 11.7:** Add the Push Changes step. - ```yaml - - name: Push changes and tags - run: git push --follow-tags origin main - # Ensure this pushes to the correct branch (e.g., main) - ``` - -* **Task 12: Add GitHub Release Creation Step** - * [x] **Sub-task 12.1:** Add the step using `softprops/action-gh-release@v1` after the push step. Use `generate_release_notes: true` for automatic notes based on conventional commits. - ```yaml - - name: Create GitHub Release - uses: softprops/action-gh-release@v1 - # This action runs implicitly on tag push, which is handled by the previous step. - # If you want more control, you can extract the tag version and trigger explicitly. - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - generate_release_notes: true # Use conventional commits for release notes - ``` - * [x] **Sub-task 12.2:** Verify the complete `release.yml` file structure and syntax. - ---- - -**### Phase 4: Documentation & Finalization** -* **Context:** This phase ensures that the new release process is documented for human developers and that the AI agent's own operating rules are updated. - -* **Task 13: Update Developer Documentation** - * [x] **Sub-task 13.1:** Locate or create a `CONTRIBUTING.md` file. - * [x] **Sub-task 13.2:** Add a section explaining the requirement to use **Conventional Commits** for all commit messages. - * [x] **Sub-task 13.3:** Explain the purpose and usage of the `npm run commit` command for guided commits. - * [x] **Sub-task 13.4:** Briefly describe the automated release workflow triggered by the GitHub Action (mention it's currently manual via `workflow_dispatch`, but can be changed later, e.g., on merges to `main`). - -* **Task 14: Update AI Agent Rules (`.clinerules` / `startup.xml`)** - * [x] **Sub-task 14.1:** Open `.clinerules` (or the relevant AI instruction file). - * [x] **Sub-task 14.2:** Add a prominent, **mandatory rule** stating: `All git commits MUST adhere to the Conventional Commits specification (https://www.conventionalcommits.org/). Example: 'feat: implement user login' or 'fix: resolve calculation error'.` - * [x] **Sub-task 14.3:** If feasible for the agent, add a recommendation or rule: `Use 'npm run commit' to create commit messages interactively, ensuring compliance.` If not feasible, emphasize strict adherence to the format in its generated messages. - -* **Task 15: Commit All Changes** - * [ ] **Sub-task 15.1:** Stage all the files modified or created during this process (`package.json`, `commitlint.config.js`, `.husky/commit-msg`, `.github/workflows/release.yml`, `CONTRIBUTING.md`, `.clinerules`, etc.). - * [ ] **Sub-task 15.2:** Create a final commit using a valid Conventional Commit message. Use `npm run commit` or `git commit -m "feat: implement automated release workflow"` (adjust type/scope if needed, e.g., `chore:` if considered maintenance). - ---- - -**Final Verification Instruction:** After committing the changes, manually trigger the `Release Automation` workflow from the GitHub Actions UI on your branch (or `main` after merging). Confirm its successful execution, including version bump, changelog update, commit/tag push, and GitHub Release creation. Report the final status. \ No newline at end of file diff --git a/project-management/task-management/todo.md b/project-management/task-management/todo.md index 7a8ba7e..0e0661d 100644 --- a/project-management/task-management/todo.md +++ b/project-management/task-management/todo.md @@ -1,13 +1,5 @@ ## Azure DevOps MCP Server Project TODO List (Granular Daily Tasks) -### Authentication and Documentation Enhancements - -- [ ] **Task 1.2**: Update documentation on package usage with npx - - **Role**: Technical Writer - - **Description**: Create examples showing how to use the package with Cursor and other environments using mcp.json configuration - -### Authentication Enhancements - - [ ] **Task 2.8**: Implement `get_work_item` handler with tests - **Role**: Full-Stack Developer - [ ] **Task 2.10**: Implement `add_work_item_comment` handler with tests