22

I'm wondering whether there are any good conventions, as far as version control goes, for developing a module that you are using both in a single Magento instance and also are wanting to release as a community module.

Initially what I attempted to do was to use modman to manage the module outside of my main Magento instance repository. But that ended up being problematic on multiple levels. Having a single repository that you can easily install to different environments or roll back in production is extremely useful, and I would even say has become a necessary part of my workflow.

What I'm doing currently is developing it inside of my site repository, and am planning to break it off into a separate repository soon. At that point, what I'll likely do is:

  • Build in my local environment within an individual module repository using modman
  • Copy changes into the site repository when I'm ready to deploy code

Hoping there's a better way?

  • did you try composer? – FlorinelChis May 14 '13 at 16:58
  • I played around with it a little bit at one point but haven't used it seriously much. Do you like it? – kalenjordan May 14 '13 at 17:03
  • yes, Vinai had a presentation at a recent Magento Meetup in London about composer. using it varies from case to case infrastructure (single web server, multi web servers). Depends on preferences. – FlorinelChis May 14 '13 at 20:18
16

We have a few modules where we have done this and what we essentially did is:

  • Setup a Git repo for the module.
  • Deploy this module into the codebase of the production site and commit everything including:
    • soft-links created by modman
    • the .modman directory which houses the cloned module repository
  • Use modman to "deploy" it into other versions and/or dev environment for dev and testing.

Doing it this way gets you the flexibility you need for module development, versions the code on the single site as well, and if you make changes to the module in the single-site codebase, you can commit those straight back to the module repository since the repo is is there in the .modman directory.

UPDATE: When I originally wrote this I failed to take into account in my answer that Git does not allow (sub) modules to be committed to a repository, in which case "committing the everything" kind of needs some elaboration!

Incidentally, this is because I've done this more often using modman to deploy modules housed in Git repos into a production codebase housed by SVN… and Subversion has no scruples preventing it from committing the entire Git tree to the VCS.

So here goes…

  1. If you are using SVN to house the production site's code, you should have no problems since Subversion has (practically) no concept of sub-modules. It won't mind.

  2. If you are using Git for the production site's code, you will have to use sub-modules to "commit everything" to the site's code repository. After using modman to clone something like this:

    modman clone ssh://git@bitbucket.org/<user>/<repo>.git
    

    You'll also want to add it as a sub-module like so:

    git submodule add ssh://git@bitbucket.org/<user>/<repo>.git .modman/<repo>
    

    Once you have done this, you should be able to add the .modman directory and .gitmodules file to the index and commit it.

    After cloning the repository which is using these modules installed via modman, simply init submodules and update:

    git submodule init
    git submodule update
    

P.S. I now use Git full-time on all new projects, so hopefully this oversight won't happen again. Sorry guys. ;)

  • Wow that sounds amazing. Going to give that a spin. – kalenjordan May 14 '13 at 17:14
  • have you also considered Submodules in git? – FlorinelChis May 14 '13 at 20:17
  • Submodules require everything be in one directory. Modman essentially creates soft-links for everything, allowing it to be spread throughout the dir structure. – davidalger May 14 '13 at 20:24
  • When you say to commit everything including the modman data, do you mean to commit the symlinks that are within the project directory structure? When I git add -A, here's what I get: monosnap.com/image/X1EoGyK12UQfYDUqA9hvpUUwq Using the modman deploy command doesn't appear to do anything different from the clone command - it just symlinks the files in (although it doesn't require VCS in order to work). – kalenjordan May 15 '13 at 0:44
  • That's correct, everything including soft links. Should have noted this above, but key here is the soft links being relative so they work in different envs. Old versions of modman didn't support them. If you don't commit them you'll need ignores for them, and have to make sure you have modman around to deploy on other envirnomenta. Internally, git stores the soft link as a txt file with the path needed to create the link when cloned. – davidalger May 15 '13 at 3:51
7

It seems that the current convention is to provide support for:

As far as directory structure, it's bare-minimum and preferably the module is installed in Community code pool.

A bare-minimum suggested directory structure would be:

.
└── app
    ├── code
    │   └── community
    │       └── YourCompany
    │           └── YourModule
    │               ├── Block
    │               ├── Model
    │               │   └── Observer.php
    │               └── etc
    │                   └── config.xml
    ├── design
    │   └── frontend
    │       └── base
    │           └── default
    │               ├── layout
    │               │   └── module.xml
    │               └── template
    │                   └── yourmodule
    └── etc
        └── modules
            └── YourCompany_YourModule.xml

Optional / nice-to-haves:

  • Github landing page with a description, some screen shots and some bulleted features.
  • Link off to an installed demo store would be nice, too
  • A screencast / two-minute overview of your product

Edit: I might have misunderstood.

Using a combinations of modman / gitignore can keep your module insular from your test environment. Using the above folder structure you can explicitly allow only your module's files to be committed / installed to your repo. In this case, David's answer is more applicable. Modman support for dev/deploy seems to be the consensus.

  • Thanks Phil. This looks like some good information as far as best practice when developing / publishing a module, but ya I was more looking for information along the lines of David's answer. – kalenjordan May 14 '13 at 17:13
  • 4
    Upvote just for an ASCII drawing – Ben Lessani - Sonassi May 14 '13 at 18:14
  • @teamsonassi: Beware, that might be as simple as copying the output from the tree command :-) – Alex May 15 '13 at 13:27
  • I wouldn't care if he did it via cowsay - ASCII art just makes answers look good :D – Ben Lessani - Sonassi May 15 '13 at 13:36
  • Be forewarned, I use cowsay and figlet.... a lot. – philwinkle May 15 '13 at 13:51
5

Even not having tried it myself yet, I would recommend using composer for that.

Versioning including dependencies

By keeping the composer.lock file in the repository, you fix the versions of all modules and can always restore a specific version (a branch, tag or an older version) by using your VCS (git checkout, svn ..) and then composer.phar install.

Drawbacks

A problem which arises, is that your deployment can easily depend on multiple sources (for example GitHub) creating multiple points of failure.

So we would need some kind of cache or proxy which stores those modules so we are always able to deploy.

Satis seems to be able to serve this purpose (see https://github.com/researchgate/broker) and my question https://stackoverflow.com/q/16211671/288568

  • 1
    thanks to Artifact (see getcomposer.org/doc/05-repositories.md#artifact ) the depending on different sources is easier to reduce and to control. Also allows the plugin architecture of composer to cache the packages on for example AWS (cant find a link to the implementation now) – Flyingmana Dec 27 '13 at 3:22
  • Shouldn't modules not depend on one another? – user2045 Jun 6 '14 at 17:26
2

Kalen,

Maybe I didn't quite catch your workflow right, but it sounded like you're developing in a magento repo locally, then separating into a modman repo. Why not just edit the ./modman/modulesname/CONTENTS in your IDE and push code to the module repo independently in the same work flow you use to develop. you can use modman for deploy to production, you can interact with the individual repo in the .modman/modulesname/ folder from cli or by adding a versioning source to your IDE, though really using .basedir to keep your repository linked paths out of your webroot is going to play better.

There is also a really nice feature of modman that many people don't seem to use. The bash script interprets a .basedir file in the .modman repository, if the file doesn't exist modman applies the symlink rules in the modman file at the same level as the .modman folder... if the .basedir file exists, the contents describe a subfolder that is the top level of your Magento code one down from the .modman path... in other words, you could run (and I do) all the base Magento versions in folders like 'BaseMagento1.9.1.0' 'BaseMagento1.14.2.0' and modman init the folder containing these. Add a .basedir file into the .modman path and you can change the contents easily. This works well for version testing.

  • Thanks, interesting stuff! Been a while since I was using this workflow! – kalenjordan Oct 13 '15 at 15:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.