capistrano v3 deploy git repository and its submodules - capistrano

With capistrano v2 submodules can be includes in the deploy by using option:
set :git_enable_submodules, 1
In v3 this does not seem to work. Is this option still supported or is there a new way to reach the same goal?

In capistrano 3.1.x and later you can implement your own SCM strategy. There is an available gem that helps with git submodule, please see: https://github.com/i-ekho/capistrano-git-submodule-strategy.
NOTE: you may have problem with the repo folder if you already tried with the default git strategy. Simply go to the deploy directory on server and remove it and then run cap deploy again to fix.

The new Pull Request "828" is trying to implement that again:
https://github.com/capistrano/capistrano/pull/828
As discussed by #coffeeaddict, this Commit is a scrap of the code you will need to deploy locally until it's bundled with the capistrano itself. Please note that you need Capistrano >= 3.1.0 to use the code.
There is also another Gist that suggest to fix some issues of the strategy above.

It turns out it's very difficult to hook into any of the git tasks of capistrano (because they don't exist until the stage is set). Besides, git archive does not in any way provide support for submodules, so that part has to be completely replaced.
Copy and paste is also not an option for obvious reasons.
So I wrote this simple gem that can replace the git scm. It uses a similiar approach to capistrano 2, by cloning the repo with its submodules. It is very simple and enough for our goals. I suspect there are not many different usages of submodules out there (if people try to avoid complications).
https://github.com/juanibiapina/capistrano-scm-gitsubmodules
Let me know if it helps you too.
UPDATE:
This module has been deprecated with capistrano 3.1.0. Try this instead: https://gist.github.com/stevenscg/8176735

As you can see in the Capistrano source code https://github.com/capistrano/capistrano/blob/master/lib/capistrano/tasks/git.rake#L34 and https://github.com/capistrano/capistrano/blob/master/lib/capistrano/tasks/git.rake#L56 it uses git archive to check out the code into the release directory.
The code is reproduced here:
desc 'Clone the repo to the cache'
task clone: :'git:wrapper' do
on roles :all do
if test " [ -f #{repo_path}/HEAD ] "
info t(:mirror_exists, at: repo_path)
else
within deploy_path do
with git_environmental_variables do
execute :git, :clone, '--mirror', repo_url, repo_path
end
end
end
end
end
desc 'Update the repo mirror to reflect the origin state'
task update: :'git:clone' do
on roles :all do
within repo_path do
execute :git, :remote, :update
end
end
end
desc 'Copy repo to releases'
task create_release: :'git:update' do
on roles :all do
with git_environmental_variables do
within repo_path do
execute :mkdir, '-p', release_path
execute :git, :archive, fetch(:branch), '| tar -x -C', release_path
end
end
end
From that we can ascertain that submodules are not supported. As the commands to clone or initialize submodules are never issued, and git-archive ignores them.
The decision was made (source: Capistrano author here) not to include submodules "out of the box" as the hooks needed to build this in, if you need it are already there, and it's trivial to write an add-on task that does what you need to checkout/update submodules in a way that works for you. The Capistrano v2 submodule support often had unexpected consequences for people.
With that in mind. It might be worth to hooking into update, to initialize and update your submodules after the update is finished, and examining ways to augment git-archive do do what you need.

Related

How to convert a github repository to local project component code?

There is a github repository that is no longer actively maintained. I want to use the code and move it into my project's components but that is tedious and not sure if that is the best approach.
I just want to bump the version of draftjs used by the repository.
Here is the repo and it uses draft js version 0.10.0
https://github.com/brijeshb42/medium-draft
My local project uses draft js version 0.11.7
This causes errors and incompatibility issues.
What is the best approach when a repository uses an outdated version of a repository used by local project?
Before forking and publishing to npm your own version of that dependencies, you might consider using the package/patch-package
Patches created by patch-package are automatically and gracefully applied when you use npm(>=5) or yarn.
No more waiting around for pull requests to be merged and published. No more forking repos just to fix that one tiny thing preventing your app from working.
# fix a bug in one of your dependencies
vim node_modules/some-package/brokenFile.js
# run patch-package to create a .patch file
npx patch-package some-package
# commit the patch file to share the fix with your team
git add patches/some-package+3.14.15.patch
git commit -m "fix brokenFile.js in some-package"
In your case, you would be patching the brijeshb42/medium-draft/package.json file.

Enabling github pre commit hooks in origin for all collaborators

first: We use a github repository in the team for some projects.
I'm using scripts defined in the pre-commit hook directory, locally (works perfect for my commits).
What I need is for every user (collaborator) to use the hooks without using symlinks or asking them to put them on their home folders.
Is there a way to set them up so the users can't commit if the scripts don't exit 0?.
Thanks.
As Henrik alluded to, in the Enterprise version, there is such a thing as the pre-receive hook. It runs server side and so you would not need to install it on each collaborator's local machine. But you are using github.com actual, and they don't allow pre receive hooks , nor do I expect they plan to; allowing indivduals to run scripts on their server isn't likely in their business plan. So that likely won't help you unless you are in a position to go to the enterprise product
There are some remedies you do have, however, but it won't be equivalent. You can , for example, set a protected branch . You could thereby make it only you can check into that branch, and you of course would be using the local hook, every one else would be using a pull request.
Additionally, you could look into LGTM (Looks Good To Me) or similar automated pull request approval system. I don't believe the official server is up but the source code is there and it could be run by someone else. LGTM allows you to set a number of different conditions that would be closer to an equivalent to your pre-op hook.
Setting up such a system might well be more effort than it is worth to you, understandable; but it is do-able.
The main problem with using pre-commit hooks that come with git is that they are local to your repos and don't get pushed to github.com. I believe under the hood, those hooks aren't even transferred up to the repo on github, and that the pre-commit hook directory itself is not available like it is on the local copy of a git repo.
(I would say more on that architecture of the pre-commit hook dir except A. I am not sure if it is covered by NDA and B. I only saw the way it was on the Enterprise product, not github actual, and C. I don't know if the structure is still exactly the same)

How to execute a client-side Git hook?

I am having problem while implementing a pre-push hook. The developers need to run a static code analyzer before they push the code to the git repo. But usually they don't and hence break the build.
Thus, I have written a pre-push hook; which is a shell script to execute the static code analysis ( and copied to .git/hooks) directory but it is not working correctly. This has to be a client-side hook but it is not working as expected. And I dont want to implement this functionality in a pre-commit or post-commit hook since I want static code analysis to be done on the developer's machine before he/she pushes the code (and not when he/she) commits the code.
Thus, please provide your insight as to how I can execute a task (static code analysis) on the client machine before git push command.
As #sestus said, hooks need to be set up client-side, they are not part of the Git repository. It makes sense if you consider that Git is a distributed system and hooks can execute arbitrary code.
What you can do is check in the script into the repository (e.g. to $REPO_ROOT/git-hooks/pre-push) and use the build toolchain of your project to set the up a symlink (ln -s ../../git-hooks/pre-push .git/hooks).

set :deploy_via, :remote_cache this option is not applied to submodules

I am using git submodule feature with capistrano. I have
set :deploy_via, :remote_cache
set :git_enable_submodules,1
Everything works great. However remote_cache option is only applied to main app. Which means that every single time I deploy the app all submodules pull in all changes and that takes a lot of time.
Is there a way to tell submodule to use :remote_cache.
Thanks
You need to go deep into capistrano sources, just search for git_enable_submodules and remote_cache.
I think there is no suitable to be used with remote_cache, but that should be no problem as you can copy code that does git_enable_submodules and write your own implementation.
When You have your solution you can fork capistrano add it to code and ask for pull request.

What is the cleverest use of source repository that you have ever seen?

This actually stems from on my earlier question where one of the answers made me wonder how people are using the scm/repository in different ways for development.
Pre-tested commits
Before (TeamCity, build manager):
The concept is simple, the build system stands as a roadblock between your commit entering trunk and only after the build system determines that your commit doesn't break things does it allow the commit to be introduced into version control, where other developers will sync and integrate that change into their local working copies
After (using a DVCS like Git, that is a source repository):
My workflow with Hudson for pre-tested commits involves three separate Git repositories:
my local repo (local),
the canonical/central repo (origin)
and my "world-readable" (inside the firewall) repo (public).
For pre-tested commits, I utilize a constantly changing branch called "pu" (potential updates) on the world-readable repo.
Inside of Hudson I created a job that polls the world-readable repo (public) for changes in the "pu" branch and will kick off builds when updates are pushed.
my workflow for taking a change from inception to origin is:
* hack, hack, hack
* commit to local/topic
* git pup public
* Hudson polls public/pu
* Hudson runs potential-updates job
* Tests fail?
o Yes: Rework commit, try again
o No: Continue
* Rebase onto local/master
* Push to origin/master
Using this pre-tested commit workflow I can offload the majority of my testing requirements to the build system's cluster of machines instead of running them locally, meaning I can spend the majority of my time writing code instead of waiting for tests to complete on my own machine in between coding iterations.
(Variation) Private Build (David Gageot, Algodeal)
Same principle than above, but the build is done on the same workstation than the one used to develop, but on a cloned repo:
How not to use a CI server in the long term and not suffer the increasing time lost staring at the builds locally?
With git, it’s a piece of cake.
First, we ‘git clone’ the working directory to another folder. Git does the copy very quickly.
Next times, we don’t need to clone. Just tell git get the deltas. Net result: instant cloning. Impressive.
What about the consistency?
Doing a simple ‘git pull’ from the working directory will realize, using delta’s digests, that the changes where already pushed on the shared repository.
Nothing to do. Impressive again.
Of course, while the build is running in the second directory, we can keep on working on the code. No need to wait.
We now have a private build with no maintenance, no additional installation, not dependant on the IDE, ran with a single command line. No more broken build in the shared repository. We can recycle our CI server.
Yes. You’ve heard well. We’ve just built a serverless CI. Every additional feature of a real CI server is noise to me.
#!/bin/bash
if [ 0 -eq `git remote -v | grep -c push` ]; then
REMOTE_REPO=`git remote -v | sed 's/origin//'`
else
REMOTE_REPO=`git remote -v | grep "(push)" | sed 's/origin//' | sed 's/(push)//'`
fi
if [ ! -z "$1" ]; then
git add .
git commit -a -m "$1"
fi
git pull
if [ ! -d ".privatebuild" ]; then
git clone . .privatebuild
fi
cd .privatebuild
git clean -df
git pull
if [ -e "pom.xml" ]; then
mvn clean install
if [ $? -eq 0 ]; then
echo "Publishing to: $REMOTE_REPO"
git push $REMOTE_REPO master
else
echo "Unable to build"
exit $?
fi
fi
Dmitry Tashkinov, who has an interesting question on DVCS and CI, asks:
I don't understand how "We’ve just built a serverless CI" cohere with Martin Fowler's state:
"Once I have made my own build of a properly synchronized working copy I can then finally commit my changes into the mainline, which then updates the repository. However my commit doesn't finish my work. At this point we build again, but this time on an integration machine based on the mainline code. Only when this build succeeds can we say that my changes are done. There is always a chance that I missed something on my machine and the repository wasn't properly updated."
Do you ignore or bend it?
#Dmitry: I do not ignore nor bend the process described by Martin Fowler in his ContinuousIntegration entry.
But you have to realize that DVCS adds publication as an orthogonal dimension to branching.
The serverless CI described by David is just an implementation of the general CI process detailed by Martin: instead of having a CI server, you push to a local copy where a local CI runs, then you push "valid" code to a central repo.
#VonC, but the idea was to run CI NOT locally particularly not to miss something in transition between machines.
When you use the so called local CI, then it may pass all the tests just because it is local, but break down later on another machine.
So is it integeration? I'm not criticizing here at all, the question is difficult to me and I'm trying to understand.
#Dmitry: "So is it integeration"?
It is one level of integration, which can help get rid of all the basic checks (like format issue, code style, basic static analysis detection, ...)
Since you have that publication mechanism, you can chain that kind of CI to another CI server if you want. That server, in turn, can automatically push (if this is still fast-forward) to the "central" repo.
David Gageot didn't need that extra level, being already at target in term of deployment architecture (PC->PC) and needed only that basic kind of CI level.
That doesn't prevent him to setup more complete system integration server for more complete testing.
My favorite? An unreleased tool which used Bazaar (a DSCM with very well-thought-out explicit rename handling) to track tree-structured data by representing the datastore as a directory structure.
This allowed an XML document to be branched and merged, with all the goodness (conflict detection and resolution, review workflow, and of course change logging and the like) made easy by modern distributed source control. Splitting components of the document and its metadata into their own files prevented the issues of allowing proximity to create false conflicts, and otherwise allowed all the work that the Bazaar team put into versioning filesystem trees to work with tree-structured data of other kinds.
Definitely Polarion Track & Wiki...
The entire bug tracking and wiki database is stored in subversion to be able to keep a complete revision history.
http://www.polarion.com/products/trackwiki/features.php