renovatebot

Stars and mentions

Last 30 days, Oct 4 – Nov 2

GitHub stars0
mentions10
01234Oct 4Oct 18Nov 2
UTC days · repositories renovatebot owns0 repositories

Package downloads

No package download history available yet.

Top repositories

renovatebot’s repositories ranked by new stars, as on trending.

Loading

Contributes to

Repositories outside renovatebot’s account where renovatebot opened or reviewed pull requests in the past 365 days.

Who noticed renovatebot

Everyone who starred or forked renovatebot’s repositories since the archive began in 2011.

Notable accounts

Ordered by the stars their own repositories have received.

Biggest fans

Accounts that starred the most of these repositories.

Breakout weeks

Each repository’s best week of new stars, with the release published around it.

Mentions

10posts
Nov 30 posts
  1. @JuanPa @coderabbitai OK fair - but I guess for github.com/renovatebot we'd be good?

    12 views
  2. Kubernetes - Automated Dependency Updates with Renovate This post is part of our ongoing series of posts for Kubernetes. In this post, we will automate dependency updates for our GitOps repository using Renovate, an open-source tool that finds outdated dependencies and raises pull requests to update them. All components in our cluster are pinned to a specific version: Helm charts in HelmRelease, Flux itself in gotk-components.yaml, and actions in our GitHub workflows. This is what GitOps expects, but nothing tells us when these versions become outdated. We hadn't touched our cluster for a while, and by the time we came back, every Helm chart had a newer release available. Checking release pages manually for each of them is error-prone and time-consuming. Renovate addresses this challenge by scanning the repository, looking up newer versions of each dependency, and raising a pull request per update with release notes attached. We stay in control by reviewing and merging, and FluxCD takes care of rolling out the change. Let's dive into setting up Renovate as a self-hosted GitHub Actions workflow. 1. Create a Token for Renovate Renovate needs a token to access the repository, push update branches and open pull requests. Let's create a fine-grained personal access token that only has access to our GitOps repository: - Repository access: Only select repositories → k8s-gitops - Read and write permission for Contents, Pull requests, Issues and Workflows - Read-only access to Metadata (added automatically) Workflows permission is needed so Renovate can update action versions in .github/workflows, and Issues is used for the Dependency Dashboard we'll see later. Next, save the token as a repository secret. gh asks for the value, so the token never ends up in shell history: gh secret set RENOVATE_TOKEN -R kiriapurv/k8s-gitops > Important: Don't forget to give the token access to the repository itself, not just the permissions. With Public repositories selected, Renovate fails on a private repository with platform-unknown-error, and only the debug log shows the actual problem: Could not resolve to a Repository with the name 'kiriapurv/k8s-gitops'. 2. Setup Renovate Workflow Let's schedule weekly Renovate runs by creating .github/workflows/renovate.yaml: name: renovate on: workflow_dispatch: inputs: logLevel: description: Renovate log level type: choice options: [info, debug] default: info schedule: - cron: "0 3 * * 1" permissions: contents: read jobs: renovate: runs-on: ubuntu-latest steps: - name: Self-hosted Renovate uses: renovatebot/github-action@2804199d260ad00c1fae0e9e842888369391c776 # v46.3.10 with: token: ${{ secrets.RENOVATE_TOKEN }} env: RENOVATE_REPOSITORIES: ${{ github.repository }} RENOVATE_GIT_AUTHOR: "Renovate Bot <3841024+kiriapurv@users.noreply.github.com>" LOG_LEVEL: ${{ inputs.logLevel || 'info' }} This configuration: - Runs every Monday at 03:00 UTC, and on demand through workflow_dispatch with an optional debug log level for troubleshooting - Pins the Renovate action to a full commit SHA instead of a tag, as this step gets a token with write access - Restricts Renovate to the current repository with RENOVATE_REPOSITORIES - Sets RENOVATE_GIT_AUTHOR so commits are made with our account instead of Renovate's default Mend address 3. Configure Renovate Next, let's tell Renovate what to look for by creating renovate.json in the root of the repository: { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ "config:recommended", "helpers:pinGitHubActionDigests" ], "timezone": "Asia/Kolkata", "flux": { "managerFilePatterns": [ "/cluster/.+\\.ya?ml$/", "/apps/.+\\.ya?ml$/" ] }, "packageRules": [ { "description": "Sample app image tags are managed by Flux image automation", "matchPackageNames": [ "ghcr.io/kiriapurv/**" ], "enabled": false } ] } This configuration includes several important customizations: - config:recommended gives us Renovate's sensible defaults, like the Dependency Dashboard and PR rate limiting - helpers:pinGitHubActionDigests pins GitHub Actions to commit digests and keeps those digests updated - flux.managerFilePatterns is the most important setting for our layout. By default, Renovate's flux manager only looks at gotk-components.yaml, so it wouldn't find the HelmRelease definitions in cluster/default/ - The packageRules entry stops updates for our sample application image, since Flux image automation already handles it as set up in Kubernetes GitOps with FluxCD - Part 3 - Automated Image Updates Before committing, let's validate the configuration with Renovate's own validator: docker run --rm -v "$PWD":/usr/src/app -w /usr/src/app renovate/renovate:44.190.1 renovate-config-validator --strict renovate.json INFO: Validating renovate.json as global config INFO: Config validated successfully against 1 file(s) Now let's commit and push these changes to our GitOps repository. 4. Validate Setup Let's run the workflow manually right away instead of waiting for Monday: gh workflow run renovate.yaml -R kiriapurv/k8s-gitops Once the run is done, the workflow log shows what Renovate found: INFO: Renovate started INFO: Repository started (repository=kiriapurv/k8s-gitops) INFO: Dependency extraction complete (repository=kiriapurv/k8s-gitops, baseBranch=main) "stats": { "managers": { "flux": {"fileCount": 9, "depCount": 9}, "github-actions": {"fileCount": 2, "depCount": 7} "total": {"fileCount": 11, "depCount": 16} INFO: Branch created (repository=kiriapurv/k8s-gitops, branch=renovate/pin-dependencies) INFO: PR created (repository=kiriapurv/k8s-gitops, branch=renovate/pin-dependencies) "prTitle": "Pin dependencies", INFO: Branch created (repository=kiriapurv/k8s-gitops, branch=renovate/fluxcd-flux2-2.x) INFO: PR created (repository=kiriapurv/k8s-gitops, branch=renovate/fluxcd-flux2-2.x) "prTitle": "Update dependency fluxcd/flux2 to v2.10.0", INFO: Repository finished (repository=kiriapurv/k8s-gitops) "cloned": true, "durationMs": 41762, "result": "done", Renovate detected 16 dependencies in 11 files and already opened two pull requests. The rest of the updates are listed in the Dependency Dashboard, an issue created and maintained by Renovate itself: !Renovate Dependency Dashboard listing rate-limited Helm chart updates All Helm charts in our cluster had an update available: | Chart | Current | Available | |---|---|---| | cilium | 1.17.1 | 1.20.4 | | cert-manager | 1.17.1 | v1.21.3 | | ingress-nginx | 4.11.3 | 4.15.1 | | kube-prometheus-stack | 69.5.2 | 69.8.2, 92.14.1 | | descheduler | 0.32.2 | 0.37.0 | | reflector | 9.0.318 | 9.1.45, 10.0.69 | | reloader | 1.3.0 | 2.2.19 | These updates are listed under Rate-Limited because config:recommended allows at most two new pull requests per hour, so a stale repository isn't flooded with PRs. Ticking a checkbox on the dashboard lifts the limit for that one update. Major versions, like kube-prometheus-stack 92, get a separate branch, so minor and major upgrades can be reviewed separately. 5. Rolling Out an Update To show the full flow, we'll upgrade Reflector, which we configured in Kubernetes - Replicate Secrets with Reflector. First, let's check which version is running now: kubectl get pods -l app.kubernetes.io/name=reflector -o jsonpath='{range .items[*]}{.metadata.name}{" "}{.spec.containers[0].image}{"\n"}{end}' reflector-dcc5cf554-4wl95 docker.io/emberstack/kubernetes-reflector:9.0.318 After ticking Update Helm release reflector to v9.1.45 on the dashboard and running the workflow again, Renovate creates a pull request with the release notes. The only line that changes: chart: spec: chart: reflector - version: "9.0.318" + version: "9.1.45" interval: 10m sourceRef: kind: HelmRepository !Renovate pull request updating the Reflector Helm release to 9.1.45 Once the pull request is merged, FluxCD picks up the change. Instead of waiting for the next polling interval, let's trigger the reconciliation: flux reconcile source git flux-system ◎ waiting for GitRepository reconciliation ✔ fetched revision main@sha1:0f4e575ef86d2bb51fce04a0301141cf8cd1a74a flux reconcile helmrelease reflector -n default ✔ HelmRelease annotated ◎ waiting for HelmRelease reconciliation ✔ applied revision 9.1.45 Now let's check if our release was upgraded: flux get helmrelease reflector -n default NAME REVISION SUSPENDED READY MESSAGE reflector 9.1.45 False True Helm upgrade succeeded for release default/reflector.v2 with chart reflector@9.1.45 kubectl get pods -l app.kubernetes.io/name=reflector NAME READY STATUS RESTARTS AGE reflector-556f7cbb75-mfvvz 1/1 Running 0 43s The new pod runs docker.io/emberstack/kubernetes-reflector:9.1.45, and the GitHub registry secret is still replicated to all namespaces: kubectl get secrets -A --field-selector metadata.name=github-registry-secret NAMESPACE NAME TYPE DATA AGE cert-manager github-registry-secret kubernetes.io/dockerconfigjson 1 602d cilium-secrets github-registry-secret kubernetes.io/dockerconfigjson 1 596d default github-registry-secret kubernetes.io/dockerconfigjson 1 609d flux-system github-registry-secret kubernetes.io/dockerconfigjson 1 602d ingress-nginx github-registry-secret kubernetes.io/dockerconfigjson 1 596d kube-node-lease github-registry-secret kubernetes.io/dockerconfigjson 1 602d kube-public github-registry-secret kubernetes.io/dockerconfigjson 1 602d kube-system github-registry-secret kubernetes.io/dockerconfigjson 1 602d monitoring github-registry-secret kubernetes.io/dockerconfigjson 1 602d reloader github-registry-secret kubernetes.io/dockerconfigjson 1 601d The update went from pull request to running pod without touching the cluster directly. 6. Retiring the Custom Flux Update Workflow In Kubernetes GitOps with FluxCD - Part 7 - Resource Optimization and Automated Version Management with Github Actions, we created a GitHub Actions workflow to regenerate gotk-components.yaml every month. Renovate's flux manager does this automatically: the Update dependency fluxcd/flux2 to v2.10.0 pull request regenerates cluster/default/flux-system/gotk-components.yaml for the new Flux version. Since both would now conflict over the same file, we removed .github/workflows/update-flux.yaml and closed its pending pull request. Renovate saw that the workflow was gone and automatically closed its own Pin dependencies pull request, which only changed that file. > Note: We are holding back the Flux v2.10.0 update and the major chart upgrades for now. They need a newer Kubernetes version, so we'll upgrade K3s first in an upcoming post. What next ? Future posts will keep bringing the cluster up to date, including: - Automated K3s upgrades with System Upgrade Controller - Migrating from ingress-nginx to Gateway API Stay tuned for each of these topics. References - Renovate Documentation - docs.renovatebot.com - Renovate Flux Manager - docs.renovatebot.com - Renovate GitHub Action - renovatebot/github-action - FluxCD Documentation - fluxcd.io

  3. [quote="Henry Schreiner, post:4, topic:109629, username:henryiii"] m not very fond of arbitrary caps, though setting a limit of uint64 (or even uint32) on each element would be have a practical benefit. [/quote] FYI, here are real issues where people may exceeded uint64 or hit arbitrary limits: - Branch and commit hash in dev segment: uv#8271 - Date and commit hash in the dev segment: uv#9572 - Timestamps in the local segment: renovate#34101 - Commit and date labels in the local segment: uv#14137 I don't personally think it needs an update, but it tool/infrastructure/library authors think it needs a clarification, I think it's fine to add that tools may reject versions based on their size of individual components or the entire version. And that can be either character limits or byte limits, whatever makes sense for the tool, I think what the limit is is different for different contexts and I'm not sure it makes sense to be explicit in the spec.

    1 comment
  4. Forgejo Actions: dind and jobs with volume mounts I set up a Forgejo runner and dind container following the example here. I then followed this guide and set runner.envs.DOCKER_HOST appropriately. My jobs that use some invocation of docker -v /workspace:/somewhere (e.g. renovatebot/github-action) don't work, which makes sense, because everything under /workspace is part of the runner's filesystem, not dind's. I'd like to be able to use such actions out of the box, if possible. What can I do about this? Is there a canonical solution? Have I configured something wrong?

    8 points · 9 comments
  5. Package.resolved の originHash は何のためにあるのか Renovate が依存を上げた PR をマージしたあと、tuist install を流すと Package.resolved の 1 行だけが書き換わるようになりました。 Package.resolved { - "originHash" : "b51d86e0d60dc9c07d7da15f1bb995c680b75f60f09f0ee586aea8f14852849d", - "originHash" : "9ea100c33d0673a7cbf638a61115d34ce142720e95d1761c390aa31ae6ec796b", "pins" : [ この originHash が何のための値なのかを、SwiftPM のソースを読み、実際に計測して確かめました。分かったことは次の 4 つです。 originHash は「この Package.resolved がどの Package.swift に対して作られたか」の目印で、改ざん検知の値ではない 一致していると、SwiftPM は依存のバージョンを選び直す計算を省ける。差が出るのは checkout が足りないとき(clone 直後や .build をキャッシュしない CI)で、今回の環境(pin 60 個)では約 20 秒だった SwiftPM 自身は、pin が変わらない限り originHash を書き直さない。だから古いまま残りやすい 実際に解決しないまま originHash だけを今の値にするのは危ない。Tuist は一致した hash を信じて推移的な依存の要求を確かめず、要求を満たさない pin をそのまま使う(再現して確かめた) 後半では、依存を自動で上げる Renovate と Dependabot で、この値の扱いがどう違うかも比べます。調べる途中で見立てを 3 回間違えたので、その話も最後に書きます。 ! SwiftPM のコードは 2026 年 10 月時点の main(7137197)、計測は macOS・Xcode 27.2(Swift 6.4.2)で行いました。 originHash はルートの manifest の SHA-256 originHash は、Package.resolved の書式のバージョン 3 で入った値です。SwiftPM は、ルートの Package.swift の tools-version が 5.10 以上のときにこの書式で書き出します。 中身は、SwiftPM の computeResolvedFileOriginHash を読むと分かります。 Sources/Workspace/Workspace+Dependencies.swift private func computeResolvedFileOriginHash(root: PackageGraphRootInput) throws -> String { var content = try root.packages.reduce(into: "") { partial, element in let path = try ManifestLoader.findManifest( packagePath: element, fileSystem: self.fileSystem, currentToolsVersion: self.currentToolsVersion ) try partial.append(self.fileSystem.readFileContents(path)) } content += root.dependencies.reduce(into: "") { partial, element in partial += element.locationString } return content.sha256Checksum } ルートパッケージの manifest のファイル内容をそのままつなげ、ルートに追加の依存があればその URL を足して、SHA-256 をとっています。ふつうのパッケージでは追加の依存は無いので、Package.swift のファイル内容の SHA-256 そのものになります。手元でも確かめられます。 $ grep originHash Package.resolved "originHash" : "9ea100c33d0673a7cbf638a61115d34ce142720e95d1761c390aa31ae6ec796b", $ shasum -a 256 Package.swift 9ea100c33d0673a7cbf638a61115d34ce142720e95d1761c390aa31ae6ec796b Package.swift ここから 3 つのことが言えます。 pin(各依存のバージョンとコミット)は計算に入っていない。Package.resolved の中身が書き換えられても、originHash では気づけない コメントを 1 文字足しただけでも値が変わる Package@swift-6.0.swift のような Swift のバージョンごとの manifest があると、使っている toolchain が選んだファイルの hash になる 一致すると、SwiftPM はバージョンの選び直しを省く originHash を入れた SwiftPM の PR(swiftlang/swift-package-manager#6698、2023 年 8 月)には、狙いがこう書かれています。 when a package.resolved file exists the dependencies resolution should stick to it, unless requested otherwise 実装では、swift package resolve やビルドが使う標準の解決(コード上は .bestEffort)の中で、この hash を比べて分岐しています(抜粋して簡略化しています)。 let currentHash = try self.computeResolvedFileOriginHash(root: root) guard storedHash == currentHash else { // 'Package.resolved' origin hash does do not match manifest dependencies. resolving and updating accordingly return try await resolveAndUpdateResolvedFile(forceResolution: false) } // 'Package.resolved' origin hash matches manifest dependencies, attempting resolution based on this file let (manifests, precomputationResult) = try await self.tryResolveBasedOnResolvedVersionsFile(...) コメントにしたメッセージは、--very-verbose を付けると実際にログに出ます(「does do not」は原文のままです)。 originHash 通る経路 やること 一致 tryResolveBasedOnResolvedVersionsFile pin のコミットで checkout し、pin が今の要求を満たすかを確かめる 不一致 resolveAndUpdateResolvedFile 足りない checkout があれば resolver を走らせる(今の pin を優先して選ぶ)。揃っていれば pin が要求を満たすかを確かめるだけ どちらの経路でも、pin が今の要求を満たすかは確かめられ(precomputeResolution か resolver)、満たさなければ解決し直します。今の pin が要求を満たしていれば、どちらの経路でもその pin がそのまま使われます。違うのは、そこにたどり着くまでの手間です。後で書く計測でも、hash が一致していてもずれていても、最終的な pin は同じでした。 なお、Package.resolved を正として扱う --force-resolved-versions と、swift package update は originHash を読みません。update は値を計算して書き込むだけです。 差が出るのは checkout が足りないとき 手間の違いがどれくらいかを、仕事で開発しているアプリの依存で測りました。Package.swift に直接書いている依存が 25 個、推移的な依存も含めた pin が 60 個あり、すべて git のリポジトリです。 まず、.build に checkout がある状態です。5 回ずつ流しました。 originHash swift package resolve 一致 0.46〜0.51 秒 古い 0.43〜0.51 秒 差はありませんでした。前の節の分岐のとおり、checkout が揃っていれば、hash がずれていても resolver は走らないからです。checkout が揃った手元の開発では、originHash が古くても遅くなりません。 次に、.build を空にした状態です。git のリポジトリは SwiftPM のキャッシュ(--cache-path)に入っているので、clone の時間はほぼ含みません。順番を入れ替えて 2 回ずつ流しました。 originHash 1 巡目 2 巡目 ログの「Computing version for」 一致 66 秒 29 秒 0 件 古い 87 秒 53 秒 60 件 一致していると、SwiftPM は pin のコミットでそのまま作業コピーを作ります。古いと resolver が走り、60 パッケージすべてについて、git のタグの一覧と、候補になるバージョンの Package.swift を読みます。ログの「Computing version for」がその作業で、これが 2 回とも約 20 秒の差になりました。clone 直後の手元や、.build をキャッシュしない CI は、毎回この分だけ遅くなります。 Tuist ではもっと差が開きます。Tuist の依存解決(SwifterPM)は、hash が一致すると swift package resolve を起動せず、自前のキャッシュから戻すだけで済ませるからです。.build が空の状態で 1 回ずつ測ると、一致で 7.4 秒、古いと 134 秒でした。 ! ネットワークから clone し直す場合は測っていません。その場合は clone の時間が大きく、差の割合は小さくなると考えています。 計測の手順と条件 コマンドは swift package --package-path <dir> --scratch-path <dir>/.build --cache-path <cache> --disable-scm-to-registry-transformation resolve で、時間は /usr/bin/time -p で測りました。 hash を一致させるときは、Package.resolved の originHash を shasum -a 256 Package.swift の値に書き換えました。古い hash は、Package.swift を変える前の値です。pin はどちらも同じです。 checkout がある状態は、同じ .build で続けて 5 回ずつ流しました。 checkout が無い状態は、毎回新しいディレクトリを作り、--scratch-path を空にしました。--cache-path は共通なので、git のリポジトリはキャッシュから取ります。1 巡目は一致→古い、2 巡目は古い→一致の順です。 Tuist の数字は、Tuist の依存解決部分を swifterpm コマンドとしてビルドし、空の --scratch-path で 1 回ずつ測りました。 回数が少なく、同じ条件でも 29 秒と 66 秒のように大きくぶれています。絶対値はマシンや負荷で変わるので、2 巡とも約 20 秒の差が出た、という点だけを読み取ってください。 SwiftPM は pin が変わらないと originHash を書き直さない これだけ効く値なのに、古いまま残りやすい理由は、SwiftPM の保存処理にあります。saveResolvedFile は、保存済みの pin と今の pin を比べて、同じなら何もせずに抜けます(抜粋です。比べている部分は日本語のコメントに置き換えました)。 Sources/Workspace/Workspace+ResolvedPackages.swift // try to load the Package.resolved store from disk so we can compare for any changes // this is needed as we want to avoid re-writing the resolved files unless absolutely necessary var needsUpdate = false if let persistedResolvedPackagesStore = try? self.resolvedPackagesStore.load() { // pin の数と、各 pin の状態を比べる(originHash は比べない) } // exist early is there is nothing to do if !needsUpdate { return } 比べているのは pin だけなので、Package.swift を変えても pin が変わらなければ、originHash は前の値のまま残ります。小さなパッケージで再現できます。 mkdir -p repro/Sources/Repro && cd repro cat > Package.swift <<'EOF' // swift-tools-version: 6.0 import PackageDescription let package = Package( name: "Repro", dependencies: [ .package(url: "apple/swift-algorithms", from: "1.1.0"), ], targets: [ .target(name: "Repro", dependencies: [.product(name: "Algorithms", package: "swift-algorithms")]), ] ) EOF echo 'import Algorithms' > Sources/Repro/Repro.swift swift package resolve grep originHash Package.resolved # shasum -a 256 Package.swift と同じ値 要求だけを変える(今の pin 1.2.1 はどちらでも満たす) sed -i '' 's/from: "1.1.0"/from: "1.2.0"/' Package.swift swift package resolve --very-verbose 2>&1 | grep "origin hash" debug: 'Package.resolved' origin hash does do not match manifest dependencies. resolving and updating accordingly grep originHash Package.resolved # 前の値のまま。何回流しても変わらない swift package update でも、pin が変わらなければ書き直しません。同じ不満は SwiftPM の Issue(#7644「V3 originHash should update more eagerly」、2024 年 6 月)にも出ていて、まだ直っていません。 依存を自動で上げるツールを使っていると、この状態にすぐなります。Renovate の Swift 対応は、Package.swift の要求を上げるときに Package.resolved の該当する pin も書き換えます。ただし originHash には触りません。このことは renovatebot/renovate#41534 に既知の制約として書かれています。マージした後に SwiftPM が解決しても、pin はすでに新しいので、originHash は古いまま残ります。 Dependabot は事情が違います。Dependabot の Swift 対応は、書き換えた Package.swift を作業用のディレクトリに置き、swift package resolve <依存> --version <バージョン> を実際に走らせて、その結果の Package.resolved を commit します(lockfile_updater.rb)。originHash も SwiftPM が計算するので、正しい値になります。以前 Dependabot を使っていたときの commit を見返すと、Package.swift を書き換えた PR でも、originHash は Package.swift の SHA-256 と一致していました。 冒頭の 1 行の diff は、ここに Tuist が絡んで出ていました。Tuist は tuist install で解決するたびに、自分で計算した originHash でファイルを書き直します。SwiftPM と違って値を最新に保つので、Renovate の PR の後に古い値が見つかると、書き直して diff を出すわけです。 解決しないまま originHash だけを直してはいけない この値がただの SHA-256 なら、Renovate が Package.swift を書き換えるついでに計算すればよさそうに見えます。私も最初はそう考えて、Renovate に提案しました(後で取り下げています)。ところが、これは Tuist を使っていると危ない直し方です。 Tuist の依存解決は、hash が一致すると swift package resolve を起動せずに pin をそのまま使います。この速い経路で確かめているのはミラーとローカルパッケージの条件だけで、推移的な依存の要求は確かめません。 一方、Renovate が書き換えるのは、上げた依存の pin だけです。たとえば GoogleSignIn-iOS を 10.0.0 に上げたとします。10.0.0 は AppAuth-iOS に from: "3.0.0" を要求しますが、Package.resolved には AppAuth-iOS 2.1.0 の pin が残ります。実際に私たちのリポジトリでも、この状態の PR がマージされていました。 この状態で originHash だけを今の値にするとどうなるかを、小さな Tuist のプロジェクトで試しました。GoogleSignIn-iOS を from: "9.2.0" で入れた状態から、Renovate と同じように Package.swift の要求と GoogleSignIn-iOS の pin だけを 10.0.0 に書き換えました。そのうえで、Tuist 4.212.0 の tuist install を流しています。 originHash tuist install checkout された AppAuth-iOS GTMAppAuth 古いまま 29 秒、成功 3.0.0 6.0.0 今の値に書き換え 3 秒、成功 2.1.0 5.0.0 古いままだと、Tuist は SwiftPM に解決を任せ、SwiftPM が AppAuth-iOS を 3.0.0 に直しました。今の値にしてあると、Tuist は速い経路で済ませました。checkout されたのは、GoogleSignIn-iOS 10.0.0 の要求(from: "3.0.0")を満たさない AppAuth-iOS 2.1.0 で、エラーも出ませんでした。古い originHash が、ちょうど「確かめ直せ」という合図になっていたわけです。 SwiftPM 自身は、どちらの経路でも pin を確かめます。同じ Package.resolved を素の swift package resolve で解決すると、hash が一致していても(ログは「origin hash matches」)、AppAuth-iOS は 3.0.0 に直りました。 再現の手順 Tuist.swift と、Tuist/Package.swift に .package(url: "google/GoogleSignIn-iOS", from: "9.2.0") だけを書いたプロジェクトで tuist install する。GoogleSignIn-iOS 9.2.0、AppAuth-iOS 2.1.0、GTMAppAuth 5.0.0 が pin される 別のプロジェクトで from: "10.0.0" にして tuist install し、10.0.0 系の依存をキャッシュに入れておく 1 の Package.resolved の GoogleSignIn-iOS の pin だけを、2 のもの(10.0.0)に書き換える。Package.swift は from: "10.0.0" にする originHash を 1 の値のまま残したものと、shasum -a 256 Tuist/Package.swift の値に書き換えたものを用意し、それぞれ空の Tuist/.build で tuist install する 結果の Package.resolved と Tuist/.build/workspace-state.json で、checkout されたバージョンを確かめる 同じ更新を Dependabot がすると、SwiftPM が解決するので AppAuth-iOS も 3.0.0 に上がり、originHash も正しい値になります。pin と originHash を一緒に、実際の解決結果で書き換えるので、この問題は起きません。 ほかにも、自動で上げる PR がそれぞれ originHash を書き換えると、どの PR も Package.resolved の 2 行目を別の値に変えることになります。そのため、1 本マージするたびに残りの PR が conflict します。 originHash を変えてよいのは、その Package.swift で実際に解決して、pin と一緒に書き込むときだけです。 どう付き合うか 使っている道具ごとに、現実的な扱い方が違います。 SwiftPM と Xcode だけを使っている場合は、古い originHash でも結果は変わらず、checkout が無いときに遅くなるだけです。ただ、今の SwiftPM には、pin を変えずに originHash だけを更新するコマンドがありません。Package.resolved を消して作り直せば hash は新しくなりますが、範囲内の新しいバージョンに pin が上がることがあります。 Tuist を使っている場合は、tuist install が書き直した 1 行の diff を、そのまま commit するのがよいと考えています。見た目だけの差分に見えますが、これを入れておくと、clone 直後や CI の install が速い経路に戻ります。 Renovate と Dependabot の違い 依存を自動で上げているなら、どちらのツールかで扱いが変わります。 Renovate Dependabot 方式 SwiftPM を動かさず、pin の文字列を書き換える Linux の上で SwiftPM を実際に動かす originHash 古いまま残る SwiftPM が計算した正しい値になる 推移的な依存の pin 取り残される SwiftPM が揃える Linux でだけ使う依存 入らない 入る PR 同士の conflict originHash の行ではぶつからない Package.swift を変える PR 同士が originHash の行でぶつかる ※ Package.swift を持つパッケージを更新する場合の比較です。Xcode プロジェクトの Package.resolved については後で書きます。 Dependabot の方が Package.resolved を正しく保てますが、代わりに Linux で解決した結果になります。Dependabot は Ubuntu の上の Swift 6.3.1 で解決します(Dockerfile)。Linux で解決するので、Apple のプラットフォームでは使わない依存まで pin に入ることがあります。 私たちのアプリでは OpenCombine がそうでした。依存している combine-schedulers は、Darwin 以外でだけ OpenCombine を使う trait を既定で有効にしています(Package@swift-6.1.swift)。macOS で解決すると OpenCombine は pin に入りませんが、Dependabot の PR には入ってきて、手で消していました。この食い違いを避けるなら、使わない OpenCombine をあえてルートの依存に書いておく手もあります。macOS で解決しても pin に入るので、Linux の結果と揃います(target を持たない manifest で確かめました)。 Dependabot の Swift も、手元の Xcode より古くなりがちです。依存に Package@swift-6.4.swift のような新しい Swift 向けの manifest が増えると、Linux と手元で読むファイルが変わり、結果がずれる可能性があります。 なお、Package.swift を持たない Xcode プロジェクトの Package.resolved を書き換える経路(xcode_lockfile_updater.rb)は、SwiftPM を動かさず、originHash を扱うコードもありません。こちらは Renovate と同じく、pin だけを書き換えます。 どちらのツールでも、いちばんきれいなのは、その PR の中で macOS で実際に解決して、結果を commit することです。たとえば Renovate のブランチで macOS の CI に tuist install を流させ、書き換わった Package.resolved を bot が PR に commit・push します。こうすると originHash だけでなく、取り残された推移的な依存の pin も一緒に直り、Linux でだけ入る依存も混ざりません。ただし swift package resolve は pin が変わらなければ originHash を書き直さないので、Tuist を使わない場合は、この方法でも hash が古いまま残ることがあります。 SwiftPM 側の修正 根本を直すため、SwiftPM に PR(swiftlang/swift-package-manager#10718)を出しました。pin が要求を満たすと確かめた後で、originHash がずれていたら hash だけを書き直す変更です。入れば Xcode でも originHash が最新に保たれるようになります。ただし代わりに、Package.swift を変えた後に 1 行の diff が出るようになり、Package.swift を触ったブランチ同士はこの行でぶつかりやすくなります。checkout が無いときの解決の速さと conflict のどちらを取るか、というトレードオフです。 見立てを 3 回間違えた話 最初は「Tuist が余計な diff を出している」と思いました。調べると、Tuist の値は SwiftPM の定義どおりの SHA-256 で、古い値を残していたのは Renovate の側でした。 次に「Renovate が originHash を計算し直せばいい」と考えました。これは前の節のとおり、Tuist では壊れた pin を通してしまうので取り下げました。 最後に「SwiftPM と Xcode では古い originHash でも遅くならない。書き直して diff を出す Tuist の方を SwiftPM に合わせればいい」と考えて、Tuist に PR(tuist/tuist#14475)を出しました。根拠は checkout がある状態の計測だけでした。checkout が無い状態を測ってみると、Tuist の書き直しこそが速さを保っていたと分かり、PR は閉じました。 近道が効くのは、ふだんの手元ではなく clone 直後や CI です。性能を確かめるときは、効いてほしい状態で測るべきだった、というのがいちばんの反省です。 originHash は「近道を使ってよいか」の目印 originHash は、Package.resolved が今の Package.swift 用かどうかを SwiftPM に伝える目印です。値が正しければ、clone 直後や CI で依存のバージョンの選び直しを省けます。ただ、SwiftPM 自身は pin が変わるまで更新しないので、古くなりがちです(#7644)。 古い値に気づいたら、実際に解決した結果と一緒に commit する。解決しないまま値だけを書き換えない。この 2 つを守れば、diff に紛れ込むこの 1 行が、クリーンな環境での解決を速くしてくれます。依存を自動で上げるなら、Dependabot は実際に解決して書き換えるので前者に当たります。ただし Linux で解決した結果になる点には気をつけてください。

  6. AIを使って対応していた依存パッケージの更新チェック、OSSのRenovateで更新検出からPR作成までを自動化。Forgejoにも対応。手動確認の手間を減らし、アプリの技術スタックを継続的に最新に保つ仕組みを構築できます。AIには定型的な更新チェックより、開発そのものに集中だ renovatebot/renovate

    10 views
  7. RenovateもActions lockfile対応しているのね👀 renovate#45190

    1 like · 111 views
  8. @iloveitaly @brandur Use Renovate. renovatebot/renovate

    1 like · 11 views
  9. Wow! Renovate now officially updates aqua-installer's aqua_version 🎉 github.com/renovatebot/renovate/releases/tag/44.9…

    16 likes · 5 reposts · 1,881 views
Trending awards, every completed day and week
Gold
01st place finishes
Silver
02nd place finishes
Bronze
03rd place finishes
Awarded repositories
0Owned by renovatebot now

No trending awards yet

None of the repositories renovatebot owns has finished in the top three of a completed trending day or week, by stars, forks or PR authors. See who is trending now.

A repository earns an award for finishing first, second or third in a completed trending day or week, ranked by new stars, new forks or pull request authors. Awards follow a repository through renames and transfers and count toward its current owner. Weeks run Monday to Sunday, UTC.