Version controlling multiple Frappe apps in a single monorepo

Greetings Frappe community,

I am facing a challenge in version controlling multiple Frappe apps in a single repository without using submodules or creating a single app to develop all features. My goal is to maintain the modular aspect of individual apps while being able to reuse them in other projects.

In my research, I discovered that I can create new apps without the git repo using the --no-git parameter alongside the new-app command. However, I am unsure if this approach will enable me to manage all apps in one repository and reuse them across multiple projects. If this approach is valid, would I just copy the individual app folder that I need, and how can I install it without a git repo using the default bench commands?

I have attempted a manual approach by removing the .git of each app and initializing a new git repo for the parent apps folder. However, I encountered errors while using the bench update command since it looks for each individual app git repo, which no longer exists. My concern with this approach is how I can install and update individual apps without a git repo later on in new projects.

While searching for a solution, I came across a GitHub issue created by @revant that discusses a monorepo solution. However, I am unsure how to implement it, and there are no details on how the repository would be managed and controlled. Here’s the link to the issue: Monorepo management · Issue #1174 · frappe/bench · GitHub

Therefore, I would like to seek guidance from the Frappe community and ask the following questions:

  1. How can I implement a monorepo approach to version control multiple Frappe apps in a single repository? I would appreciate any suggestions on this matter.
  2. If I used the manual approach that I already tried, how can I install and update individual apps without a git repo later on in new projects?
  3. Has anyone successfully implemented the monorepo method mentioned in the issue above? If so, could you share how you implemented it and how it works?

I would appreciate your help and suggestions on this matter.

Thank you for your time and consideration.

Best regards

I only use containers so at the point where I build images, the runners have ability to pre-process the apps from monorepos. Build script copies the apps into image (COPY --chown=frappe:frappe ./apps /home/frappe/frappe-bench/apps) and RUN bench setup requirements && bench build --production. In cases where monorepo is must, use this workaround.

If you are okay with containers then base it on frappe_docker/development containers. Create a repo for your developers to bootstrap predictable development environment.

Mention in official docs: frappe_docker/development.md at main · frappe/frappe_docker · GitHub.

Check example that uses mysql, castlecraft / frappe_mysql_devcontainer · GitLab.

Use ssh keys and mount them in containers for easy pull of private repos. Add apps.json and additional scripts that help developers setup environment in devcontainers.

You can even build your own development image based on frappe/bench:latest if you need additional development tools. Example custom image devcontainer · main · castlecraft / k8s_bench_interface · GitLab.

Add repo for each project, client or environment. Scripts integrate and build the environment from version of frappe framework and other apps specified when it does the bench init.

1 Like

thank you so much revant!

Actually, after a lot of thinking especially i don’t use containers that much, I am going to stick to the default approach and i will manage each app individual to leverage the modular design so i can reuse them without any issues.

But thank you for the suggestion.