diff --git a/docs/updater.md b/docs/updater.md index 796d4f0f..f3ccfad5 100644 --- a/docs/updater.md +++ b/docs/updater.md @@ -19,6 +19,7 @@ docker run --rm -t \ -e DEPENDABOT_EXTRA_CREDENTIALS= \ -e DEPENDABOT_ALLOW_CONDITIONS= \ -e DEPENDABOT_IGNORE_CONDITIONS= \ + -e DEPENDABOT_COMMIT_MESSAGE_OPTIONS= \ -e DEPENDABOT_BRANCH_NAME_SEPARATOR= \ -e DEPENDABOT_MILESTONE= \ -e DEPENDABOT_UPDATER_OPTIONS= \ @@ -49,6 +50,7 @@ docker run --rm -t \ -e DEPENDABOT_EXTRA_CREDENTIALS='[{"type":"npm_registry","token":"","registry":"npm.fontawesome.com"}]' \ -e DEPENDABOT_ALLOW_CONDITIONS='[{"dependency-name":"django*","dependency-type":"direct"}]' \ -e DEPENDABOT_IGNORE_CONDITIONS='[{"dependency-name":"@types/*"}]' \ + -e DEPENDABOT_COMMIT_MESSAGE_OPTIONS='{"prefix":"(dependabot)"}' \ -e DEPENDABOT_BRANCH_NAME_SEPARATOR='/' \ -e DEPENDABOT_MILESTONE=123 \ -e DEPENDABOT_UPDATER_OPTIONS='goprivate=true,kubernetes_updates=true' \ @@ -76,6 +78,7 @@ docker run --rm -t \ -e DEPENDABOT_EXTRA_CREDENTIALS='[{"type":"npm_registry","token":"","registry":"npm.fontawesome.com"}]' \ -e DEPENDABOT_ALLOW_CONDITIONS='[{"dependency-name":"django*","dependency-type":"direct"}]' \ -e DEPENDABOT_IGNORE_CONDITIONS='[{"dependency-name":"@types/*"}]' \ + -e DEPENDABOT_COMMIT_MESSAGE_OPTIONS='{"prefix":"(dependabot)"}' \ -e DEPENDABOT_BRANCH_NAME_SEPARATOR='/' \ -e DEPENDABOT_MILESTONE=123 \ -e DEPENDABOT_UPDATER_OPTIONS='goprivate=true,kubernetes_updates=true' \ @@ -108,6 +111,7 @@ To run the script, some environment variables are required. |DEPENDABOT_EXTRA_CREDENTIALS|**_Optional_**. The extra credentials in JSON format. Extra credentials can be used to access private NuGet feeds, docker registries, maven repositories, etc. For example a private registry authentication (For example FontAwesome Pro: `[{"type":"npm_registry","token":"","registry":"npm.fontawesome.com"}]`)| |DEPENDABOT_ALLOW_CONDITIONS|**_Optional_**. The dependencies whose updates are allowed, in JSON format. This can be used to control which packages can be updated. For example: `[{\"dependency-name\":"django*",\"dependency-type\":\"direct\"}]`. See [official docs](https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/configuration-options-for-dependency-updates#allow) for more.| |DEPENDABOT_IGNORE_CONDITIONS|**_Optional_**. The dependencies to be ignored, in JSON format. This can be used to control which packages can be updated. For example: `[{\"dependency-name\":\"express\",\"versions\":[\"4.x\",\"5.x\"]}]`. See [official docs](https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/configuration-options-for-dependency-updates#ignore) for more.| +|DEPENDABOT_COMMIT_MESSAGE_OPTIONS|**_Optional_**. The commit message options, in JSON format. For example: `{\"prefix\":\"(dependabot)\"}`. See [official docs](https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#commit-message) for more.| |DEPENDABOT_LABELS|**_Optional_**. The custom labels to be used, in JSON format. This can be used to override the default values. For example: `[\"npm dependencies\",\"triage-board\"]`. See [official docs](https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/customizing-dependency-updates#setting-custom-labels) for more.| |DEPENDABOT_REVIEWERS|**_Optional_**. The identifiers of the users to review the pull requests, in JSON format. These shall be added as optional approvers. For example: `[\"23d9f23d-981e-4a0c-a975-8e5c665914ec\",\"62b67ef1-58e9-4be9-83d3-690a6fc67d6b\"]`. |DEPENDABOT_ASSIGNEES|**_Optional_**. The identifiers of the users to be assigned to the pull requests, in JSON format. These shall be added as required approvers. For example: `[\"be9321e2-f404-4ffa-8d6b-44efddb04865\"]`. | diff --git a/extension/task/IDependabotConfig.ts b/extension/task/IDependabotConfig.ts index 0bbf8d22..d4573617 100644 --- a/extension/task/IDependabotConfig.ts +++ b/extension/task/IDependabotConfig.ts @@ -48,6 +48,7 @@ export interface IDependabotUpdate { * Assignees. */ assignees?: string; + commitMessage?: string; /** * The milestone to associate pull requests with. */ @@ -92,7 +93,7 @@ export interface IDependabotRegistry { * The protocol is optional. If not specified, `https://` is assumed. */ url?: string | null | undefined; - "index-url"?: string | null | undefined; // only flor python_index + "index-url"?: string | null | undefined; // only for python_index /** * The URL of the registry to use to access the dependencies. diff --git a/extension/task/index.ts b/extension/task/index.ts index 7010061f..c08af2ba 100644 --- a/extension/task/index.ts +++ b/extension/task/index.ts @@ -110,6 +110,12 @@ async function run() { dockerRunner.arg(["-e", `DEPENDABOT_IGNORE_CONDITIONS=${ignore}`]); } + // Set the commit message options + let commitMessage = update.commitMessage; + if (commitMessage) { + dockerRunner.arg(["-e", `DEPENDABOT_COMMIT_MESSAGE_OPTIONS=${commitMessage}`]); + } + // Set the requirements that should not be unlocked if (variables.excludeRequirementsToUnlock) { dockerRunner.arg(["-e", `DEPENDABOT_EXCLUDE_REQUIREMENTS_TO_UNLOCK=${variables.excludeRequirementsToUnlock}`]); diff --git a/extension/task/utils/parseConfigFile.ts b/extension/task/utils/parseConfigFile.ts index da8e6a0c..032e3e65 100644 --- a/extension/task/utils/parseConfigFile.ts +++ b/extension/task/utils/parseConfigFile.ts @@ -191,6 +191,9 @@ function parseUpdates(config: any): IDependabotUpdate[] { assignees: update["assignees"] ? JSON.stringify(update["assignees"]) : undefined, + commitMessage: update["commit-message"] + ? JSON.stringify(update["commit-message"]) + : undefined, }; if (!dependabotUpdate.packageEcosystem) { diff --git a/server/Tingle.Dependabot/Models/Dependabot/DependabotConfiguration.cs b/server/Tingle.Dependabot/Models/Dependabot/DependabotConfiguration.cs index 1786e58e..c9f1e5f3 100644 --- a/server/Tingle.Dependabot/Models/Dependabot/DependabotConfiguration.cs +++ b/server/Tingle.Dependabot/Models/Dependabot/DependabotConfiguration.cs @@ -63,6 +63,8 @@ public record DependabotUpdate public List? Allow { get; set; } [JsonPropertyName("ignore")] public List? Ignore { get; set; } + [JsonPropertyName("commit-message")] + public DependabotCommitMessage? CommitMessage { get; set; } [JsonPropertyName("labels")] public List? Labels { get; set; } [JsonPropertyName("milestone")] @@ -153,6 +155,18 @@ public IEnumerable Validate(ValidationContext validationContex } } +public class DependabotCommitMessage +{ + [JsonPropertyName("prefix")] + public string? Prefix { get; set; } + + [JsonPropertyName("prefix-development")] + public string? PrefixDevelopment { get; set; } + + [JsonPropertyName("include")] + public string? Include { get; set; } +} + public class DependabotPullRequestBranchName { [Required] diff --git a/server/Tingle.Dependabot/Workflow/UpdateRunner.cs b/server/Tingle.Dependabot/Workflow/UpdateRunner.cs index 7051cd6d..79983d15 100644 --- a/server/Tingle.Dependabot/Workflow/UpdateRunner.cs +++ b/server/Tingle.Dependabot/Workflow/UpdateRunner.cs @@ -275,6 +275,7 @@ internal async Task> CreateEnvironmentVariables(Proj .AddIfNotDefault("DEPENDABOT_VERSIONING_STRATEGY", update.VersioningStrategy) .AddIfNotDefault("DEPENDABOT_ALLOW_CONDITIONS", ToJson(update.Allow)) .AddIfNotDefault("DEPENDABOT_IGNORE_CONDITIONS", ToJson(update.Ignore)) + .AddIfNotDefault("DEPENDABOT_COMMIT_MESSAGE_OPTIONS", ToJson(update.CommitMessage)) .AddIfNotDefault("DEPENDABOT_LABELS", ToJson(update.Labels)) .AddIfNotDefault("DEPENDABOT_BRANCH_NAME_SEPARATOR", update.PullRequestBranchName?.Separator) .AddIfNotDefault("DEPENDABOT_MILESTONE", update.Milestone?.ToString()); diff --git a/updater/bin/update_script.rb b/updater/bin/update_script.rb index 9677264e..b1948789 100644 --- a/updater/bin/update_script.rb +++ b/updater/bin/update_script.rb @@ -17,7 +17,6 @@ require "dependabot/file_updaters" require "dependabot/pull_request_creator" require "dependabot/pull_request_updater" -require "dependabot/config/file_fetcher" require "dependabot/simple_instrumentor" require "dependabot/bundler" @@ -243,10 +242,26 @@ def allow_conditions_for(dep) # Setup Ignore conditions # # DEPENDABOT_IGNORE_CONDITIONS Example: [{"dependency-name":"ruby","versions":[">= 3.a", "< 4"]}] ################################################################################################## -unless ENV["DEPENDABOT_IGNORE_CONDITIONS"].to_s.strip.empty? - $options[:ignore_conditions] = JSON.parse(ENV.fetch("DEPENDABOT_IGNORE_CONDITIONS", nil)) +ignores = JSON.parse(ENV.fetch("DEPENDABOT_IGNORE_CONDITIONS", nil)) || [] +$options[:ignore_conditions] = ignores.map do |ic| + Dependabot::Config::IgnoreCondition.new( + dependency_name: ic[:"dependency-name"], + versions: ic[:versions], + update_types: ic[:"update-types"] + ) end +################################################################################################## +# Setup Commit Message Options # +# DEPENDABOT_COMMIT_MESSAGE_OPTIONS Example: {"prefix":"(dependabot)"} +################################################################################################## +commit_message = JSON.parse(ENV.fetch("DEPENDABOT_COMMIT_MESSAGE_OPTIONS", nil)) || {} +$options[:commit_message_options] = Dependabot::Config::UpdateConfig::CommitMessageOptions.new( + prefix: commit_message[:prefix], + prefix_development: commit_message[:"prefix-development"] || commit_message[:prefix], + include: commit_message[:include] +) + ################################################################# # Setup Labels # # DEPENDABOT_LABELS Example: ["npm dependencies","triage-board"] @@ -273,25 +288,10 @@ def allow_conditions_for(dep) # Get ignore versions for a dependency def ignored_versions_for(dep) - if $options[:ignore_conditions].any? - ignore_conditions = $options[:ignore_conditions].map do |ic| - Dependabot::Config::IgnoreCondition.new( - dependency_name: ic["dependency-name"], - versions: ic["versions"], - update_types: ic["update-types"] - ) - end - Dependabot::Config::UpdateConfig.new(ignore_conditions: ignore_conditions) - .ignored_versions_for( - dep, - security_updates_only: $options[:security_updates_only] - ) - else - $update_config.ignored_versions_for( - dep, - security_updates_only: $options[:security_updates_only] - ) - end + $update_config.ignored_versions_for( + dep, + security_updates_only: $options[:security_updates_only] + ) end # rubocop:disable Metrics/PerceivedComplexity @@ -472,36 +472,10 @@ def show_diff(original_file, updated_file) branch: $options[:branch] ) -## Read the update configuration if present -puts "Looking for configuration file in the repository ..." -$config_file = begin - # Using fetcher_args as before or in the examples will result in the - # config file not being found if the directory specified is not the root. - # This happens because the files are checked relative to the supplied directory. - # https://github.com/dependabot/dependabot-core/blob/c5cd618812b07ece4a4b53ea18d80ad213b077e7/common/lib/dependabot/config/file_fetcher.rb#L29 - # - # To solve this, the FileFetcher for the Config should have its own source - # with the directory pointing to the root. Cloning makes it much easier - # since we are only making the change for fetching the config file. - # - # See https://github.com/tinglesoftware/dependabot-azure-devops/issues/399 - cfg_source = $source.clone - cfg_source.directory = "/" - cfg_file = Dependabot::Config::FileFetcher.new( - source: cfg_source, - credentials: $options[:credentials], - options: $options[:updater_options] - ).config_file - puts "Using configuration file at '#{cfg_file.path}' 😎" - Dependabot::Config::File.parse(cfg_file.content) -rescue Dependabot::RepoNotFound, Dependabot::DependencyFileNotFound - puts "Configuration file was not found, a default config will be used. 😔" - Dependabot::Config::File.new(updates: []) -end -$update_config = $config_file.update_config( - $package_manager, - directory: $options[:directory], - target_branch: $options[:branch] +## Create the update configuration (we no longer parse the file because of BOM and type issues) +$update_config = Dependabot::Config::UpdateConfig.new( + ignore_conditions: $options[:ignore_conditions], + commit_message_options: $options[:commit_message_options] ) if $options[:requirements_update_strategy]