Skip to content
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

Add Task V2; Use Dependabot-CLI to perform updates #1318

Merged
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
aca48f0
Split extension task in to V1 and V2
rhyskoedijk Sep 1, 2024
eae688c
Basic support for running update using dependabot-cli
rhyskoedijk Sep 1, 2024
83bd07a
Add missing update job configs
rhyskoedijk Sep 2, 2024
943c35c
Move update output processing to dedicated class; Add DevOps API client
rhyskoedijk Sep 2, 2024
7de7611
Codespell skip package-lock.json
rhyskoedijk Sep 2, 2024
cdbe004
Clean-up
rhyskoedijk Sep 2, 2024
c49852d
Implement create pull request
rhyskoedijk Sep 3, 2024
e10dffa
Merge commit '84dececf9f0db9ac5addd20f16a54d8234d291dd' into feature/…
rhyskoedijk Sep 3, 2024
47e3863
Implement groups, auto-complete, auto-approve, pull request propertie…
rhyskoedijk Sep 3, 2024
ce5b5cc
Clean up
rhyskoedijk Sep 3, 2024
81728ca
Set task V1 as deprecated, task V2 as preview
rhyskoedijk Sep 3, 2024
ac81a88
Restructure extension task to better support multiple version
rhyskoedijk Sep 3, 2024
a3000cf
Fix typos
rhyskoedijk Sep 3, 2024
49b851a
Fix build
rhyskoedijk Sep 4, 2024
8c456d3
Fix build
rhyskoedijk Sep 4, 2024
3c00a2a
Merge commit '8c456d3d72aa5ba4f61f06d4df8e3045638ac0e7' into feature/…
rhyskoedijk Sep 4, 2024
7f781ce
Merge remote-tracking branch 'origin/main' into feature/task_v2_depen…
rhyskoedijk Sep 4, 2024
189ee76
Fix merge issues
rhyskoedijk Sep 4, 2024
47a592a
Remove unused task inputs
rhyskoedijk Sep 5, 2024
431a981
Fix for 'convertPlaceholder' not accepted built-in DevOps variable na…
rhyskoedijk Sep 5, 2024
0aae477
Implement closing pull requests
rhyskoedijk Sep 5, 2024
21c5a71
Implement updating pull requests
rhyskoedijk Sep 7, 2024
ad57091
Use default branch name if target branch not configured
rhyskoedijk Sep 7, 2024
f9ba274
Implement approving pull requests
rhyskoedijk Sep 7, 2024
f49bdae
Add task inputs for pr commit author email and name
rhyskoedijk Sep 7, 2024
85d28a7
Implement open pull request limit config
rhyskoedijk Sep 7, 2024
021e513
Cleanup temporary files after task completion
rhyskoedijk Sep 7, 2024
5b2d29d
Add configuration placeholders for dependabot component images
rhyskoedijk Sep 7, 2024
ebebd9f
Implement more config options
rhyskoedijk Sep 9, 2024
db2c6e8
Implement dependency list snapshots, which are stored in the DevOps p…
rhyskoedijk Sep 9, 2024
2ba73d4
Add task input option for storing dependency list
rhyskoedijk Sep 10, 2024
9a72706
Implement experiments
rhyskoedijk Sep 10, 2024
39704b8
Implement requirements-update-strategy and lockfile-only configs
rhyskoedijk Sep 10, 2024
612df86
Fix typo
rhyskoedijk Sep 10, 2024
3231240
Implement PR reviewers, work item references, and labels
rhyskoedijk Sep 13, 2024
15b5799
Add start commands for each task version, use V2 by default
rhyskoedijk Sep 13, 2024
fffdf66
Merge remote-tracking branch 'origin/main' into feature/task_v2_depen…
rhyskoedijk Sep 13, 2024
05b1cdb
Merge remote-tracking branch 'origin/main' into feature/task_v2_depen…
rhyskoedijk Sep 17, 2024
c230fee
Update V1 task.json version numbers when publishing the extension
rhyskoedijk Sep 17, 2024
bc1d550
Update documentation
rhyskoedijk Sep 19, 2024
bd534fa
Update documentation
rhyskoedijk Sep 19, 2024
046e929
Update documentation
rhyskoedijk Sep 19, 2024
dbed1f9
Update documentation
rhyskoedijk Sep 20, 2024
ecca888
Typo
rhyskoedijk Sep 20, 2024
4f693e4
Update documentation
rhyskoedijk Sep 20, 2024
0be8391
Fix reference to undefined `this.cachedUserIds`
rhyskoedijk Sep 21, 2024
8ea41ad
Use case insensitive comparision when parsing "System.Debug" variable
rhyskoedijk Sep 21, 2024
c031b47
Fix dependabot tool path detection in agents where `$PATH` does not c…
rhyskoedijk Sep 21, 2024
c69a3f6
Add more logging
rhyskoedijk Sep 21, 2024
d361188
Fix for task reporting success when pull request creation failed
rhyskoedijk Sep 21, 2024
440fda3
Add more logging; Fix formatting
rhyskoedijk Sep 21, 2024
8d55760
Fix 'labels' config parsing
rhyskoedijk Sep 21, 2024
2434018
Implement "targetUpdateIds" task input option
rhyskoedijk Sep 21, 2024
c1c3930
Fix error when using multiple update blocks in dependabot.yml with th…
rhyskoedijk Sep 21, 2024
0803a30
Only install dependabot once; cache the tool path once known
rhyskoedijk Sep 21, 2024
47998c7
Add migration warning to complete V1 pull requests before migrating t…
rhyskoedijk Sep 21, 2024
bbba684
Process updates synchronously when using multiple update blocks in de…
rhyskoedijk Sep 21, 2024
affe505
Fix typos
rhyskoedijk Sep 21, 2024
5978e76
Report the total number of failed update jobs in the task result
rhyskoedijk Sep 21, 2024
94f654a
Include stack trace when errors are logged, to help with diagnosing i…
rhyskoedijk Sep 21, 2024
5450d1d
Fix inverted logic for "abandonUnwantedPullRequests"
rhyskoedijk Sep 21, 2024
a9f6deb
Fix error handling
rhyskoedijk Sep 21, 2024
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
2 changes: 1 addition & 1 deletion .codespellrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[codespell]
skip = .git,*.pdf,*.svg,pnpm-lock.yaml,yarn.lock
skip = .git,*.pdf,*.svg,pnpm-lock.yaml,yarn.lock,package-lock.json
# some modules, parts of regexes, and variable names to ignore, some
# misspellings in fixtures/external responses we do not own
ignore-words-list = caf,bu,nwo,nd,kernal,crate,unparseable,couldn,defintions
7 changes: 5 additions & 2 deletions .github/workflows/extension.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,12 @@ jobs:

- name: Update version numbers in task.json
run: |
echo "`jq '.version.Major=${{ steps.gitversion.outputs.major }}' extension/tasks/dependabot/dependabotV1/task.json`" > extension/tasks/dependabot/dependabotV1/task.json
echo "`jq '.version.Minor=${{ steps.gitversion.outputs.minor }}' extension/tasks/dependabot/dependabotV1/task.json`" > extension/tasks/dependabot/dependabotV1/task.json
echo "`jq '.version.Major=1' extension/tasks/dependabot/dependabotV1/task.json`" > extension/tasks/dependabot/dependabotV1/task.json
echo "`jq '.version.Minor=34' extension/tasks/dependabot/dependabotV1/task.json`" > extension/tasks/dependabot/dependabotV1/task.json
echo "`jq '.version.Patch=${{ github.run_number }}' extension/tasks/dependabot/dependabotV1/task.json`" > extension/tasks/dependabot/dependabotV1/task.json
echo "`jq '.version.Major=${{ steps.gitversion.outputs.major }}' extension/tasks/dependabot/dependabotV2/task.json`" > extension/tasks/dependabot/dependabotV2/task.json
echo "`jq '.version.Minor=${{ steps.gitversion.outputs.minor }}' extension/tasks/dependabot/dependabotV2/task.json`" > extension/tasks/dependabot/dependabotV2/task.json
echo "`jq '.version.Patch=${{ github.run_number }}' extension/tasks/dependabot/dependabotV2/task.json`" > extension/tasks/dependabot/dependabotV2/task.json
mburumaxwell marked this conversation as resolved.
Show resolved Hide resolved

- name: Create Extension (dev)
run: >
Expand Down
248 changes: 173 additions & 75 deletions README.md

Large diffs are not rendered by default.

84 changes: 74 additions & 10 deletions docs/extension.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,24 @@

- [Using the extension](#using-the-extension)
- [Development guide](#development-guide)
- [Getting the development environment ready](#getting-the-development-environment-ready)
- [Building the extension](#building-the-extension)
- [Installing the extension](#installing-the-extension)
- [Running the unit tests](#running-the-unit-tests)
* [Getting the development environment ready](#getting-the-development-environment-ready)
* [Building the extension](#building-the-extension)
* [Installing the extension](#installing-the-extension)
* [Running the task locally](#running-the-task-locally)
* [Running the unit tests](#running-the-unit-tests)
- [Architecture](#architecture)
* [Task V2 high-level update process diagram](#task-v2-high-level-update-process-diagram)


# Using the extension

See the extension [README.md](../extension/README.md).
Refer to the extension [README.md](../extension/README.md).

# Development guide

## Getting the development environment ready

First, ensure you have [Node.js](https://docs.docker.com/engine/install/) v18+ installed.
Next, install project dependencies with npm:
Install [Node.js](https://docs.docker.com/engine/install/) v18 or higher; Install project dependencies using NPM:

```bash
cd extension
Expand All @@ -31,25 +34,86 @@ cd extension
npm run build
```

To generate the Azure DevOps `.vsix` extension package for testing, you'll first need to [create a publisher account](https://learn.microsoft.com/en-us/azure/devops/extend/publish/overview?view=azure-devops#create-a-publisher) on the [Visual Studio Marketplace Publishing Portal](https://marketplace.visualstudio.com/manage/createpublisher?managePageRedirect=true). After this, override your publisher ID below and generate the extension with:
To then generate the a Azure DevOps `.vsix` extension package for testing, you'll first need to [create a publisher account](https://learn.microsoft.com/en-us/azure/devops/extend/publish/overview?view=azure-devops#create-a-publisher) for the [Visual Studio Marketplace Publishing Portal](https://marketplace.visualstudio.com/manage/createpublisher?managePageRedirect=true). After this, use `npm run package` to build the package, with an override for your publisher ID:

```bash
npm run package -- --overrides-file overrides.local.json --rev-version --publisher your-publisher-id-here
```

## Installing the extension

To test the extension in Azure DevOps, you'll first need to build the extension `.vsix` file (see above). After this, [publish your extension](https://learn.microsoft.com/en-us/azure/devops/extend/publish/overview?view=azure-devops#publish-your-extension), then [install your extension](https://learn.microsoft.com/en-us/azure/devops/extend/publish/overview?view=azure-devops#install-your-extension).
To test the extension in a Azure DevOps organisation:
1. [Build the extension `.vsix` package](#building-the-extension)
1. [Publish the extension to your publisher account](https://learn.microsoft.com/en-us/azure/devops/extend/publish/overview?view=azure-devops#publish-your-extension)
1. [Share the extension with the organisation](https://learn.microsoft.com/en-us/azure/devops/extend/publish/overview?view=azure-devops#share-your-extension).

## Running the task locally

To run the latest task version:
```bash
npm start
```

To run a specific task version:
```bash
npm run start:V1 # runs dependabotV1 task
npm run start:V2 # runs dependabotV2 task
```
## Running the unit tests

```bash
cd extension
npm test
```

# Architecture

## Task V2 high-level update process diagram
High-level sequence diagram illustrating how the `dependabotV2` task performs updates using [dependabot-cli](https://github.com/dependabot/cli). For more technical details, see [how dependabot-cli works](https://github.com/dependabot/cli?tab=readme-ov-file#how-it-works).

```mermaid
sequenceDiagram
participant ext as Dependabot DevOps Extension
participant agent as DevOps Pipeline Agent
participant devops as DevOps API
participant cli as Dependabot CLI
participant core as Dependabot Updater
participant feed as Package Feed

ext->>ext: Read and parse `dependabot.yml`
ext->>ext: Write `job.yaml`
ext->>agent: Download dependabot-cli from github
ext->>+cli: Execute `dependabot update -f job.yaml -o update-scenario.yaml`
cli->>+core: Run update for `job.yaml` with proxy and dependabot-updater docker containers
core->>devops: Fetch source files from repository
core->>core: Discover dependencies
loop for each dependency
core->>feed: Fetch latest version
core->>core: Update dependency files
end
core-->>-cli: Report outputs
cli->>cli: Write outputs to `update-sceario.yaml`
cli-->>-ext: Update completed

ext->>ext: Read and parse `update-sceario.yaml`
loop for each output
alt when output is "create_pull_request"
ext->>devops: Create pull request source branch
ext->>devops: Push commit to source branch
ext->>devops: Create pull request
ext->>devops: Set auto-approve
ext->>devops: Set auto-complete
end
alt when output is "update_pull_request"
ext->>devops: Push commit to pull request
ext->>devops: Update pull request description
ext->>devops: Set auto-approve
ext->>devops: Set auto-complete
end
alt when output is "close_pull_request"
ext->>devops: Create comment thread on pull request with close reason
ext->>devops: Abandon pull request
ext->>devops: Delete source branch
end
end

```
61 changes: 61 additions & 0 deletions docs/migrations/v1-to-v2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@

> [!WARNING]
> **:construction: Work in progress;** `dependabot@V2` is still under development and this document may change without notice up until general availability (GA).

# Table of Contents
- [Summary of changes V1 → V2](#summary-of-changes-v1-v2)
- [Breaking changes V1 → V2](#breaking-changes-v1-v2)
- [Todo before general availability](#todo-before-general-availability)

# Summary of changes V1 → V2
V2 is a complete re-write of the Dependabot task; It aims to:

- Resolve the [numerous private feed/registry authentication issues](https://github.com/tinglesoftware/dependabot-azure-devops/discussions/1317) that currently exist in V1;
- More closely align the update logic with the GitHub-hosted Dependabot service;

The task now uses [Dependabot CLI](https://github.com/dependabot/cli) to perform dependency updates, which is the _[currently]_ recommended approach for running Dependabot. See [extension task architecture](../extension.md#architecture) for more details on the technical changes and impact to the update process.

# Breaking changes V1 → V2

### New pipeline agent requirements; "Go" must be installed
Dependabot CLI requires [Go](https://go.dev/doc/install) (1.22+) and [Docker](https://docs.docker.com/get-started/get-docker/) (with Linux containers).
If you use [Microsoft-hosted agents](https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops&tabs=yaml#software), we recommend using the [ubuntu-latest](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md) image, which meets all task requirements.
For self-hosted agents, you will need to install Go 1.22+.

### Security-only updates and "fixed vulnerabilities" are not implemented (yet)
Using configuration `open-pull-requests-limit: 0` will cause a "not implemented" error. This is [current limitation of V2](../../README.md#unsupported-features-and-configurations). A solution is still under development and is expected to be resolved before general availability.
See: https://github.com/dependabot/cli/issues/360 for more technical details.

### Task Input `updaterOptions` has been renamed to `experiments`
Renamed to match Dependabot Core/CLI terminology. The input value remains unchanged. See [configuring experiments](../../README.md#configuring-experiments) for more details.

### Task Input `failOnException` has been removed
Due to the design of Dependabot CLI, the update process can no longer be interrupted once the update has started. Because of this, the update will now continue on error and summarise all error at the end of the update process.

### Task Input `excludeRequirementsToUnlock` has been removed
This was a customisation/workaround specific to the V1 update script that can no longer be implemented with Dependabot CLI as it is not an official configuration option.

### Task Input `dockerImageTag` has been removed
This is no longer required as the [custom] [Dependabot Updater image](../updater.md) is no longer used.

### Task Input `extraEnvironmentVariables` has been removed
Due to the containerised design of Dependabot CLI, environment variables can no longer be passed from the task to the updater process. All Dependabot config must now set via `dependabot.yaml` or as task inputs. The following old environment variables have been converted to task inputs:

| Environment Variable | New Task Input |
|--|--|
|DEPENDABOT_AUTHOR_EMAIL|authorEmail|
|DEPENDABOT_AUTHOR_NAME|authorName|


## Todo before general availability
Before removing the preview flag from V2 `task.json`, we need to:
- [x] Open an issue in Dependabot-CLI, enquire how security-advisories are expected to be provided **before** knowing the list of dependencies. (https://github.com/dependabot/cli/issues/360)
- [ ] Convert GitHub security advisory client in `vulnerabilities.rb` to TypeScript code
- [ ] Implement `security-advisories` config once the answer the above is known
- [x] Review `task.json`, add documentation for new V2 inputs
- [x] Update `\docs\extension.md` with V2 docs
- [x] Update `\extension\README.MD` with V2 docs
- [x] Update `\README.MD` with V2 docs
- [ ] Do a general code tidy-up pass (check all "TODO" comments)
- [ ] Add unit tests for V2 utils scripts
- [ ] Investigate https://zod.dev/
10 changes: 6 additions & 4 deletions docs/server.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
- [Why should I use the server?](#why-should-i-use-the-server)
- [Composition](#composition)
- [Deployment](#deployment)
- [Single click deployment](#single-click-deployment)
- [Deployment Parameters](#deployment-parameters)
- [Deployment with CLI](#deployment-with-cli)
- [Service Hooks and Subscriptions](#service-hooks-and-subscriptions)
* [Single click deployment](#single-click-deployment)
* [Deployment Parameters](#deployment-parameters)
* [Deployment with CLI](#deployment-with-cli)
* [Service Hooks and Subscriptions](#service-hooks-and-subscriptions)
- [Keeping updated](#keeping-updated)

# Why should I use the server?
Expand Down Expand Up @@ -59,10 +59,12 @@ The deployment exposes the following parameters that can be tuned to suit the se
|githubToken|Access token for authenticating requests to GitHub. Required for vulnerability checks and to avoid rate limiting on free requests|No|<empty>|
|imageTag|The image tag to use when pulling the docker containers. A tag also defines the version. You should avoid using `latest`. Example: `1.1.0`|No|<version-downloaded>|

> [!NOTE]
> The template includes a User Assigned Managed Identity, which is used when performing Azure Resource Manager operations such as deletions. In the deployment it creates the role assignments that it needs. These role assignments are on the resource group that you deploy to.

## Deployment with CLI

> [!IMPORTANT]
> Ensure the Azure CLI tools are installed and that you are logged in.

For a one time deployment, it is similar to how you deploy other resources on Azure.
Expand Down
49 changes: 31 additions & 18 deletions docs/updater.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@

> [!WARNING]
> **Deprecated;** Use of the Dependabot Updater image is no longer recommended since v2.0; The "updater" component is considered an internal to Dependabot and is not intended to be run directly by end-users. There are known limitations with this image, see [unsupported features and configuration](../README.md#unsupported-features-and-configurations) for more details.

# Table of Contents

- [Running the updater](#running-the-updater)
- [Environment variables](#environment-variables)
* [Environment Variables](#environment-variables)
- [Development guide](#development-guide)
- [Getting the development environment ready](#getting-the-development-environment-ready)
- [Building the Docker image](#building-the-docker-image)
- [Running your code changes](#running-your-code-changes)
- [Running the code linter](#running-the-code-linter)
- [Running the unit tests](#running-the-unit-tests)
* [Getting the development environment ready](#getting-the-development-environment-ready)
* [Building the Docker image](#building-the-docker-image)
* [Running your code changes](#running-your-code-changes)
* [Running the code linter](#running-the-code-linter)
* [Running the unit tests](#running-the-unit-tests)

# Running the updater

First, you need to pull the docker image locally to your machine:
[Build](#building-the-docker-image) or pull the docker image:

```bash
docker pull ghcr.io/tinglesoftware/dependabot-updater-<ecosystem>
```

Next create and run a container from the image. The full list of container options are detailed in [Environment variables](#environment-variables); at minimum the command should be:
Create and run a container based on the image. The full list of container options are detailed in [environment variables](#environment-variables); at minimum the command should be:

```bash
docker run --rm -t \
Expand All @@ -38,7 +41,8 @@ docker run --rm -t \
ghcr.io/tinglesoftware/dependabot-updater-<ecosystem> update_script
```

An example, for Azure DevOps Services:
<details>
<summary>Example, for Azure DevOps Services</summary>

```bash
docker run --rm -t \
Expand All @@ -55,7 +59,10 @@ docker run --rm -t \
ghcr.io/tinglesoftware/dependabot-updater-nuget update_script
```

An example, for Azure DevOps Server:
</details>

<details>
<summary>Example, for Azure DevOps Server</summary>

```bash
docker run --rm -t \
Expand All @@ -75,9 +82,11 @@ docker run --rm -t \
ghcr.io/tinglesoftware/dependabot-updater-nuget update_script
```

</details>

## Environment Variables

To run the script, some environment variables are required.
The following environment variables are required when running the container.

|Variable Name|Supported Command(s)|Description|
|--|--|--|
Expand Down Expand Up @@ -135,10 +144,12 @@ To run the script, some environment variables are required.

## Getting the development environment ready

First, ensure you have [Docker](https://docs.docker.com/engine/install/) and [Ruby](https://www.ruby-lang.org/en/documentation/installation/) installed.
On Linux, you'll need the the build essentials and Ruby development packages too; These are typically `build-essentials` and `ruby-dev`.
Install [Docker](https://docs.docker.com/engine/install/) and [Ruby](https://www.ruby-lang.org/en/documentation/installation/).

> [!NOTE]
> If developing in Linux, you'll also need the the build essentials and Ruby development packages; These are typically `build-essentials` and `ruby-dev`.

Next, install project build tools with bundle:
Install the project build tools using Bundle:

```bash
cd updater
Expand All @@ -159,21 +170,23 @@ docker build \
.
```

In some scenarios, you may want to set `BASE_VERSION` to a specific version instead of "latest".
See [updater/Dockerfile](../updater/Dockerfile) for a more detailed explanation.
> [!TIP]
> In some scenarios, you may want to set `BASE_VERSION` to a specific version instead of "latest".
> See [updater/Dockerfile](../updater/Dockerfile) for a more detailed explanation.

## Running your code changes

To test run your code changes, you'll first need to build the updater Docker image (see above), then run the updater Docker image in a container with all the required environment variables (see above).
To test run your code changes, you'll first need to [build the Docker image](#building-the-docker-image), then run the Docker image in a container with all the [required environment variables](#environment-variables).

## Running the code linter

```bash
cd updater
bundle exec rubocop
bundle exec rubocop -a # to automatically fix any correctable offenses
```

> [!TIP]
> To automatically fix correctable linting issues, use `bundle exec rubocop -a`
## Running the unit tests

```bash
Expand Down
Loading