Skip to content

build(ci): add Dependabot configuration for all package ecosystems - #9089

Open
DoDiODev wants to merge 2 commits into
apache:mainfrom
DoDiODev:pr/wave5-dependabot
Open

build(ci): add Dependabot configuration for all package ecosystems#9089
DoDiODev wants to merge 2 commits into
apache:mainfrom
DoDiODev:pr/wave5-dependabot

Conversation

@DoDiODev

@DoDiODev DoDiODev commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds .github/dependabot.yml so that dependency updates arrive as reviewable
pull requests instead of periodic manual audits.

This is a configuration-only change. No source file, build step or runtime
behaviour is touched, and rolling it back means deleting one file.

The configuration contains seven update entries across 19 directory entries:

Ecosystem Directories Manifests found
gomod /backend go.mod
npm /config-ui package.json + yarn.lock
npm /e2e package.json (no lockfile)
pip /backend/python, /backend/python/pydevlake, /backend/python/plugins/azuredevops, /backend/python/test/fakeplugin, /grafana/scripts 2 × requirements.txt, 3 × pyproject.toml + poetry.lock
docker /backend, /config-ui, /grafana, /devops/docker/lake-builder, /.devcontainer, /devops/deployment/k8s 6 Dockerfiles + k8s-deploy.yaml
docker-compose /, /.devcontainer, /devops/deployment/temporal, /backend/test/e2e/remote 4 Compose files
github-actions / 14 workflows + .github/actions/auto-cherry-pick

Design decisions

Weekly schedule, five open pull requests per ecosystem. Enough to keep the
tree moving without flooding review capacity.

Minor and patch updates are grouped, majors stay separate. A grouped pull
request keeps low-risk churn to a single review; a major change deserves its own
discussion. This mirrors how the recent manual dependency batches were split.

commit-message.prefix: build(deps). .github/workflows/commit-msg.yml
rejects any commit that does not match its conventional-commit pattern. The
prefix was verified against that exact regular expression, including the grouped
form (build(deps): bump the … group across 5 directories with 3 updates) and
the development-dependency form (build(deps-dev): …).

Language base images are pinned deliberately, so they are ignored. In Docker
tag semantics python:3.11 → python:3.14 and golang:1.26 → golang:1.27 are
minor updates. They are not dependency bumps, though: the Python tag has to
match what the Poetry lockfiles resolve against, and the Go tag has to match the
go directive in backend/go.mod and the toolchain used by CI. Both are
therefore ignored for minor as well as major updates and remain a conscious,
manual decision. node is ignored for majors only, because the build image
tracks the active LTS line and Node 26 is not an LTS release.

versioning-strategy: increase for /e2e. That directory declares
"@playwright/test": "^1.58.2" and has no lockfile. With the default strategy
Dependabot only rewrites a manifest once a release leaves the declared range, so
the entry would have produced nothing while still looking configured.

git2go is never bumped automatically. It is ABI-coupled to the libgit2
version installed in the builder image; a mismatch fails at link time.

Action pinning

Most workflows reference actions by tag. The docker/* actions are pinned to a
commit SHA with a # vX.Y.Z comment, for example:

uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f  # v7.1.0

Dependabot updates such a pin to the new commit SHA and rewrites the version
comment, so the pinning style is preserved rather than replaced by a tag.

Dependabot never proposes changing the namespace of an action. Moving to a
differently owned action stays a manual step, which matters here because ASF
infrastructure maintains an allow-list of permitted actions.

Files that are not valid workflows are not read at all — this includes
.github/workflows/codespell.yml.action-blocked-by-asf and
go-checklist.yml.bak. The blocked Codespell action is therefore left alone.

Deferred upgrades

Every ignore entry carries a comment explaining why it exists, so it can be
removed once the reason no longer applies:

Entry Reason
typescript (major) TypeScript 7 is the native-port compiler; adopting it means validating the whole build chain at once
node (major) Node 26 is not an LTS release
github.com/swaggo/swag (major) swag v2 is still a release candidate and requires regenerating every swagger annotation
github.com/libgit2/git2go/* ABI-coupled to libgit2
go the toolchain directive moves together with CI and the base images
mysql (major, Docker and Compose) keep the database on the selected MySQL 8.4 LTS line; the registry exposes unrelated higher numeric tags such as 26.7.0
python, golang, devcontainers/go (major + minor) runtime decisions, see above; Dependabot strips the registry host from the dependency name
jenkins/jenkins, atlassian/jira-software, atlassian/bitbucket-server in Compose deliberately conservative compatibility fixtures, not runtime dependencies

Compose files use their own ecosystem. The docker-compose updater covers
docker-compose.datasources.yml, .devcontainer/docker-compose.yml,
devops/deployment/temporal/docker-compose-temporal.yml and
backend/test/e2e/remote/docker-compose.test.yml. The three datasource images
listed above are ignored; regular database image updates remain enabled, while
MySQL major changes remain a deliberate manual decision.

Not covered

Stating this explicitly, because a configuration file can otherwise suggest more
coverage than it provides:

  • docker-compose-dev-mysql.yml and
    docker-compose-dev-postgresql.yml
    — the Compose ecosystem exists, but its
    current filename matcher accepts only one hyphenated segment after
    compose; these two multi-suffix names are not fetched. Their database and
    OAuth2 Proxy images remain manual.
  • Workflow container: and services: images — the github-actions
    ecosystem only updates uses: references. Compose updates therefore still
    require a consistency check against the database service images in CI.
  • backend/scripts/install-mockery.sh — a tool version inside a shell
    script.
  • apache/skywalking-eyes@main — a branch reference rather than a version.
  • Unpinned entries in backend/python/requirements.txt — without a version
    constraint there is nothing to raise.

Validation

  • YAML parses cleanly.
  • Validated against the SchemaStore dependabot-2.0.json schema (Draft 7) with
    no violations, which also confirms the plural directories key and every
    update-types value used.
  • All 19 directory entries exist and contain the expected manifest. The
    Compose filename matcher was tested against all six non-release Compose
    files: four match and the two documented dev files do not.
  • The commit message convention was checked against the regular expression in
    .github/workflows/commit-msg.yml for six representative bot commit forms.

Verified on a fork before opening this PR

This configuration was run against a fork with version updates enabled. On
2026-09-01 it produced 17 pull requests across five ecosystems, which
confirms the behaviour that matters here:

  • Grouping works. js-minor-patch bundled 21 updates into a single PR,
    actions-minor-patch bundled 4, and python-minor-patch bundled 3 across two
    directories. Major bumps stayed outside the groups, as intended.
  • Action pins stay pins. The github-actions group PR rewrote SHAs to new
    SHAs and carried the # vX.Y.Z comment along, e.g.
    docker/setup-qemu-action@ce36039… # v4.0.0 became
    docker/setup-qemu-action@96fe6ef… # v4.2.0. No pin was downgraded to a tag.
  • versioning-strategy: increase is required for /e2e. It produced
    update @playwright/test requirement from ^1.58.2 to ^1.62.1 - a bump that
    would otherwise stay silent, because the new release already satisfies the
    declared caret range and that directory has no lockfile.
  • The ignore rules hold. typescript is at 6.0.3 with 7.0.2 available and
    no PR was raised. The language images (node, golang, python) were
    likewise left alone.
  • open-pull-requests-limit throttles. The github-actions ecosystem
    stopped exactly at its limit of 5.

The Compose entry was exercised in a subsequent fork run on 2026-09-02. It
processed all four configured files. PostgreSQL was correctly proposed from
18.4-alpine to 18.6-alpine, but MySQL was proposed from 8.4.11 to the
unrelated numeric tag 26.7.0 in all four directories. This surfaced one more
issue that is fixed in this branch:

  • mysql now ignores version-update:semver-major in both the docker and
    docker-compose blocks. Patch and minor updates within the selected 8.4 LTS
    line remain enabled.
  • The corrected file was validated again against the SchemaStore Draft 7 schema
    with zero violations and copied byte-for-byte to the fork test branch.
  • Dependabot then closed all four incorrect pull requests (updated README for volumes error #37-Add Gitlab collector v1.0 #40) itself,
    commented that MySQL was no longer being updated, and deleted all four head
    branches. This is a direct behavioural test of the ignore rule rather than
    only a schema check.

Two issues surfaced during that run and are already fixed in this branch:

  1. dependency-name: mcr.microsoft.com/devcontainers/go never matched, because
    Dependabot strips the registry host from the dependency name. Using
    devcontainers/go fixes it - after the change Dependabot closed the
    superfluous PR itself with "Looks like devcontainers/go is no longer being
    updated by Dependabot"
    .
  2. Explicit labels were dropped. Dependabot only creates its default labels
    automatically; labels named in the configuration must already exist, and none
    of the ones originally chosen exist in this repository. Every PR carried a
    "The following labels could not be found" warning. Without the key,
    Dependabot applies and creates its defaults, so no repository setup is
    required up front. Maintainers can add their own labels later if they want
    them.

Known limitation: the gomod ecosystem

The sixth ecosystem, gomod, could not be verified. It fails for a reason that
is independent of this configuration: backend/mocks/ is gitignored while
tracked sources such as helpers/unithelper import it, so go mod tidy cannot
resolve those packages and Dependabot aborts after every version bump.

The same failure reproduces on a plain checkout without Dependabot involved:

go: github.com/apache/incubator-devlake/helpers/unithelper imports
        github.com/apache/incubator-devlake/mocks/core/dal: no matching versions for query "latest"

Generating the mocks first makes go mod tidy exit cleanly and leaves go.mod
and go.sum byte-identical, so the module itself is consistent.

This is tracked separately in #9088. Until it is
resolved, the gomod block in this file will not produce pull requests. It is
kept in place so that Go updates start working as soon as the underlying issue
is fixed - reviewers may of course prefer to drop the block until then.

Rollback

Delete the file. Dependabot reevaluates open version-update pull requests when
the configuration changes and may close obsolete ones automatically, as the
fork test demonstrated for all four ignored MySQL-major pull requests. Any pull
request that remains open after reevaluation must be closed manually.

@DoDiODev
DoDiODev force-pushed the pr/wave5-dependabot branch from 4a13a21 to 099c443 Compare September 2, 2026 09:03
@DoDiODev

DoDiODev commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Open question for maintainers: automatic merging after a trial period?

This pull request deliberately does not enable any form of automatic
merging - every Dependabot pull request will need a human merge. Whether that
stays the case is a maintainer decision, and it is easier to make once there is
some data, so this is only a question, not a proposal to change anything here.

For context, since it is a common misconception: Dependabot itself cannot merge.
The automerged_updates key disappeared with Dependabot Preview in 2021 and
.github/dependabot.yml has no auto-merge setting at all. What people call
"Dependabot auto-merge" today is three separate pieces, none of them in this
file:

  1. the repository setting Allow auto-merge, which for an ASF repository is
    an INFRA/.asf.yaml matter;
  2. branch protection with required status checks on main - without it,
    auto-merge merges immediately and the CI signal is worthless;
  3. a small workflow (~30 lines) that reads dependabot/fetch-metadata and calls
    gh pr merge --auto --squash only when update-type is
    version-update:semver-patch (and optionally …-minor).

Two details make this cheap for this repository specifically: Dependabot pull
requests are branches in the repository rather than fork pull requests, so they
do not sit in action_required and the checks run on their own; and a squash
merge takes the pull request title as the commit message, which already carries
the build(deps): … prefix that .github/workflows/commit-msg.yml requires.

The questions, concretely:

  1. Is automatic merging something you want at all, or do you prefer every
    dependency change to pass a human review, regardless of severity?
  2. If yes - how long should the trial period be in which everything is merged by
    hand? The schedule here is weekly, so an observation window of roughly
    6-8 weeks (about 6-8 update cycles) would show how often a grouped
    minor/patch pull request is green and mergeable unchanged, and how often it
    actually needs work. A longer window is of course fine; the point is to
    decide on evidence rather than on a feeling.
  3. What scope would you be comfortable with? A staged rollout would be the
    careful version: start with patch only, github-actions and docker,
    and extend to the npm/pip minor+patch groups only if the first stage was
    uneventful. Majors would never be in scope.
  4. Can INFRA enable Allow auto-merge and the required status checks on main?
    Without both, the workflow is pointless, so this is worth clarifying before
    anyone writes it.

One optional addition that pairs well with this: Dependabot's cooldown key can
delay a pull request until a release is a few days old, which takes the edge off
the "compromised release published minutes ago" scenario that automatic merging
otherwise amplifies. It is not used in this configuration and could be added in
the same follow-up.

If the answer to (1) is yes, we are happy to prepare that follow-up pull request
(the workflow file plus, if wanted, the cooldown entries) once the trial period
has run. Nothing in the present pull request depends on the answer.

@DoDiODev
DoDiODev force-pushed the pr/wave5-dependabot branch from 099c443 to f601196 Compare September 2, 2026 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant