dependabot / dependabot-core

🤖 Dependabot's core logic for creating update PRs.
https://docs.github.com/en/code-security/dependabot
MIT License
4.72k stars 1.02k forks source link

Dependencies spanning package managers (react native) #935

Closed sterlingwes closed 2 years ago

sterlingwes commented 5 years ago

Hello! First of all, we love dependabot at Wealthsimple 🙏

We have unique requirements using React Native in that we have dependencies that require simultaneous updates to our package.json (NPM) and Podfile (Cocoapods) for dependencies that have JS ↔️ native iOS bindings.

A recent example is a dependabot bump to react-native-image-picker. We merged this PR forgetting that it requires an update to our Podfile / Podfile.lock to reference the new version.

I've toyed with some ideas, including having dependabot open PRs against a branch that tracks master, and anytime the PR is green but the merge to master is red, kick off some CI job that bumps the cocoapod dependency. That seems like a bit too much overhead and the tracking branch would get out of sync easily.

Are there any plans to support this use case or any ideas on how I could implement this in a somewhat automated way?

connorshea commented 5 years ago

As another example: this is also true of the webpacker gem and @rails/webpacker from npm

pvinis commented 5 years ago

Is there anything happening about this?

rebelagentm commented 5 years ago

@feelepxyz @hmarr Thoughts on this?

feelepxyz commented 5 years ago

This would be sweet but would be a pretty significant piece of work with our current architecture where each package manager is run in isolation 😔We'd probably solve this in future by allowing you to customise your own update groups that could span across several projects/package managers.

Not sure we want to do anything automated here as there is no way I aware of to know which updates to group, so would probably have to resort to a set of maintained rules where we say which dependencies need to updated in groups which doesn't seem ideal.

pvinis commented 5 years ago

Is there a way to run a script after an upgrade maybe?

It could be a work around for now. So when we upgrade anything in package.json or specific things in package.json, we run a bash script that is running pod install after that?

feelepxyz commented 5 years ago

@pvinis ah there's no way to run any scripts post install and probably not going to add this to Dependabot. I think the way to do this would be to use GitHub Actions to listen for Dependabot PRs and run your scripts there to update the PR.

TimPetricola commented 4 years ago

For anyone interested by a solution to update React Native dependencies with dependabot, following @feelepxyz's idea of having a GitHub Action, I'm now using the following one, which works quite well:

name: Update Cocoapods Dependencies
on:
  push:
    branches:
      - dependabot/npm_and_yarn/**
  pull_request:
    branches:
      - dependabot/npm_and_yarn/**

jobs:
  run:
    name: Run pod install
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v2

      - name: Install Packages
        run: yarn install --non-interactive --frozen-lockfile

      - name: Cache pods
        uses: actions/cache@v1
        with:
          path: ios/Pods
          key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
          restore-keys: |
            ${{ runner.os }}-pods-

      - name: Install Cocoapods Packages
        run: pushd ios && pod install --verbose && popd

      - uses: stefanzweifel/git-auto-commit-action@v4.1.1
        with:
          commit_message: Bump Cocoapods Packages
          branch: ${{ github.head_ref }}

It listens to any push/PR from dependabot with a npm/yarn dependency, updates pods and commit the changes if they exist.

isilher commented 4 years ago

Thank you very much for sharing your workflow @TimPetricola!

Two things we noticed while applying it to our project, that may be of use to you and others:

  1. Using just on: push: branches: will trigger on all dependabot PRs as far as we could see. Having both triggers there may cause extra runs (and it's not a cheap run 🤑 ).
  2. Triggering on the filter pattern dependabot/npm_and_yarn/* will miss any branches containing forward slashes. This is a pattern we see a lot, for example @react-navigation/native or @react-native-community/async-storage. To fix this, we simply added another ⭐ : dependabot/npm_and_yarn/**. See also: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet

Hope this helps!

a-tokyo commented 4 years ago

Here's an updated version of @TimPetricola's awesome work allowing for these extras:

Github Gist: React Native support for dependabot with pod install

.github/workflows/dependabot_rn_support.yml:

name: Update Cocoapods Dependencies after Dependabot package upgrade
on:
  push:
    branches:
      - dependabot/npm_and_yarn/**
  pull_request:
    branches:
      - dependabot/npm_and_yarn/**

jobs:
  run:
    name: Run pod install
    runs-on: macos-latest
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v2

      - name: Get yarn cache
        id: yarn-cache
        run: echo "::set-output name=dir::$(yarn cache dir)"
      - uses: actions/cache@v1
        with:
          path: ${{ steps.yarn-cache.outputs.dir }}
          key: ${{ runner.os }}-node-12.x-yarn-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-node-12.x-yarn-

      - uses: actions/setup-node@v1
        with:
          node-version: 12.x
          registry-url: https://registry.npmjs.org/

      - name: Install Packages
        run: yarn install --frozen-lockfile
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

      - name: Cache pods
        uses: actions/cache@v1
        with:
          path: ios/Pods
          key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
          restore-keys: |
            ${{ runner.os }}-pods-

      - name: Install Cocoapods Packages
        run: pushd ios && pod install --verbose && popd

      - name: Generate Commit Message
        id: generate_commit_message
        # eg: ⬆️ Bump Cocoapods Packages for apple-signin-auth-1.4.0
        run: |
          branch=${GITHUB_REF#refs/heads/}
          # add `[dependabot skip]` prefix so Dependabot force pushes any rebases over our changes triggering the action again
          commit_message="[dependabot skip] :arrow_up: Bump Cocoapods Packages for${branch//dependabot\/npm_and_yarn\// }"
          echo ::set-output name=commit_message::$commit_message

      - uses: stefanzweifel/git-auto-commit-action@v4.1.1
        with:
          branch: ${{ github.head_ref }}
          commit_message: ${{ steps.generate_commit_message.outputs.commit_message }}
a-tokyo commented 4 years ago

Sidenote: An issue that arrises when using a github action is the following:

If you attempt to run @dependabot rebase after the action has run, dependabot will fail to rebase and respond with the following message:

Looks like this PR has been edited by someone other than Dependabot. That means Dependabot can't rebase it - sorry!

If you're happy for Dependabot to recreate it from scratch, overwriting any edits, you can request @dependabot recreate.
TimPetricola commented 4 years ago

Thanks @A-Tokyo I'm definitely taking updating my workflow with the timeout and yarn cache :)

For the dependabot sidenote, you can always run @dependabot recreate and it will override all changes, and then the workflow will run again

a-tokyo commented 4 years ago

My please @TimPetricola! I will keep the gist up to date as I go as well 🚀

Thanks for the info, quite useful!

jurre commented 4 years ago

Sidenote: An issue that arrises when using a github action is the following:

If you attempt to run @dependabot rebase after the action has run, dependabot will fail to rebase and respond with the following message:

Looks like this PR has been edited by someone other than Dependabot. That means Dependabot can't rebase it - sorry!

If you're happy for Dependabot to recreate it from scratch, overwriting any edits, you can request @dependabot recreate.

This is not well documented, but you can add [dependabot skip] in the commit message, and Dependabot will force push any rebases over your changes, and the action should run again.

a-tokyo commented 4 years ago

@jurre Ha! Thanks for the info!

I think this should do the trick, I will update the snippet now and test it.

Updated gist

jeffwidman commented 2 years ago

👋 Hey there! Sorry for the glacially slow response... we've been a bit buried the past few years, and only just now starting to dig through some of our backlog.

This feature would be great and surely prevent some footgun PR merges. However, I'm going to close this as "not planned" (at least natively in dependabot-core) since it would be difficult for us to track/maintain all the various related things that need to get bumped...

We've bandied about trying to make the updater logic pluggable such that people could write custom updaters that tell Dependabot "bump this and this and this" and then it'd handle opening the PR and fetching metadata... but that's a very hand wavy idea at this point with a ton of difficult edge cases... so we may never figure out a clean way to implement it.

For now, the GitHub Actions solutions are the best way to go since they can fit that stop-gap of "automated-yet-custom-to-your-project" in a way that Dependabot core cannot.