Deploy solution which includes external projects - appharbor

My project have the references to the bunch of projects from another solution (this solution also linked to own Git repository), but for convinience (to be able debug and modify them from one solution) I include these projects to my web-project solution which I want to deploy on AppHarbor. Maybe it could be said that these are sub-modules of my solution. But now I can't figure out proper way to deploy the solution on AppHarbor.
More structured description:
--Solution
------DeployedProject
------[SolutionFolderForExternalProjects]
---------Proj1ReferencedFromDeployedProject
----------Proj2ReferencedFromDeployedProject
Solution - linked to repo1
Proj1 and Proj2 - also belong external solution which linked to repo2, still ADDED to the repo1 explecitly -
git add SolutionFolderForExternalProjects/
How I should handle this sort of deployment?

AppHarbor really needs all dependencies pushed for us to successfully build you project. Generally, having one solution reference projects in some other random location on your local drive and checked into a different repository is probably not an optimal model. It's also bound to cause problems if some other person has to check out and build your code.
You should consider either combining the two solution structures into one repository (you can still have multiple solution files, see the AppHarbor solution file convention). Alternatively, package the respective dependencies up as NuGet packages and include them in your project using NuGet.

Related

Determine Maven provided dependencies

I've inherited a few maven projects which have added a /dependencies directory to capture Java jar libraries that aren't part of the project war and must be installed by a DevOps into a Tomcat installation.
The libraries in this directory seem to fall into four categories:
"provided" scope libraries,
downstream dependencies of those provided libraries, and
discoverable implementations of api jars
"mystery" libraries, i.e., not available in an external repository, and maybe unsure where they ever came from.
Is there a strategy to get Maven to help manage these dependencies and perhaps fetch them for external install?
There are probably several strategies to choose from.
Number one: leave it as it is. If it works and the build is reproducible (on different environments) that seems one valid solution.
The "mystery" part of the build might not be more of an issue for new people working with it.
I think it is valid to create an own maven module to be delivered to the infrastructure team. This module can contain the jars in the /dependencies folder.
What you would need to do is create a pom.xml and add all dependencies currently in that directory (of course not the transitive ones). The magic ones would need to go in a repository proxy (nexus, artifactory, ...). If you don't have a maven repository yet: you want one! (its easy to setup and it does help a lot!)
I would then use the assembly plugin or some ant task to build the zip do be delivered. So the infrastructure team is able to just unzip / copy the files where they need to be. This step can then even be scripted (so the upload / unzip is done through SSH or something like that).
This is probably only one way to do it. I would assume to resolve the jar's in the /dependencies directory may be a bit of a pain.
The advantage is obviously that you document and simplify the management of those libraries. I would also assume if you update some of them it is easier across branches to merge since there are no binary files around. So it may be worth the effort.

Multiple Maven modules with dependency on a JAR

In my multi-module Maven project, suppose I have two modules, car and horse. They both depend on a JAR file, transport.jar, a file not available in any online Maven repositories. As such, I need to find a way to make these modules depend on a file found somewhere in the project folder structure.
From what I understand, the default Maven solution would be to manually register the JAR file in the local repository. While this would work on a development machine, it breaks on the build server, which clears its local repository before each build.
I've been searching online on how to do this on and off for a while and found some helpful things, but nothing that completely works.
For instance, a common answer is to add a dependency to the file using <scope>system</scope>. However, not only do others claim that it's extremely bad practice to do so, it also doesn't work on the build server. (On a side note, I would also like to point out that using absolute paths to the JAR is also out of the question due to, again, it being built on several different machines.)
A more useful method I found was to define a local repository in the POM file, pointing towards the path file:${project.basedir}/lib. (Such as in this article) Unfortunately, if I place the JAR and repository definition in the car POM, I cannot successfully add a dependency to the JAR in horse. I've tried both with and without an additional reference to car in horse, as well as defining a second repository in horse, pointing to file:${project.basedir}/../car/lib. This problem would also remain if I tried to make a third module, transport-lib, specifically for wrapping the JAR dependency.
I could most likely add the JAR file to both modules and define two separate module-local repositories, but I really don't want to unless I have to due to the need to keep the two (often updated) JARs in sync etc.
So, my question is as follows: Can someone give me a confirmed-to-work method to have two modules depend on the same JAR file inside the project, given the parameters and restrictions mentioned?
Best solution is to use a repository manager like Archiva, Artifactory or Nexus and install that artifact into the repository manager. Afterwards you can use this artifact directly in your pom files without any issue.
Don't use the scope system, cause it will cause other problem after a release for other etc.

Coding when NuGet (or Maven) is used for enterprise project dependencies?

Suppose that a large project is split into multiple projects, each housed in an individual Mercurial repository (as per What's a good way to organize projects with shared dependencies in Mercurial?).
Suppose also, that a dependency manager is being used internally (we're using NuGet, but the same could apply to Maven) so that:
ProjectA depends on Ninject and MongoDB
ProjectB depends on ProjectA, and log4net
Projects A and B can be built independently; NuGet automatically downloads both OSS and internal dependencies from a NuGet server (ProGet in this case).
Suppose finally, that ProjectB depends on v1.2.3.4-SNAPSHOT of ProjectA, and that a CI server continually updates the ProjectA.1.2.3.4-SNAPSHOT package in the NuGet server. Thereby ProjectB will always be developed against the latest checked in changes of ProjectA.
What if related changes are required in both Project A and B? What neat and clever ways are there to do this properly? Some ideas:
Developer checks out Project A and B. Changes are made to A, built, and checked in. Developer waits for CI server to build and update the NuGet server. Changes are made to B, built, and checked in. (I dislike this as code is being checked in as part of development process.)
Developer checks out Project A and B, and rewires B to use A source as a dependency (instead of NuGet package ProjectA). Changes are done to both A and B. Check in is performed for both A and B together after proper testing, but developer must ensure dependency changes are not checked in.
I'm not particularly good at this, so I think that someone will blow my ideas out of the water with something quite clever.
I don't know about how NuGet does it, but with Maven, your second idea works fine, apart from 'rewires B to use A source as a dependency' being unnecessary. You would just build A locally (using install) and it would be installed to the your local Maven repo. Then when building B, it will pick up the newly built A, rather than the one from the central repo.
I could think of the following with nuget :
In Project A drop the packages at a central location (in this example I am placing it in c:\localpackages)
Build A with
MSBUILD.exe /t:Build,Package A.csproj
With Project B you could add a .nuget\nuget.config that specifies
(you can read more about specifying package folder location here http://docs.nuget.org/docs/release-notes/nuget-2.1)
This should pick the changes made by project A. It might become tricky when you have different versions of nuget package dropped for A
Hope this helps.

package managers, project structure and migration

I have a solution with multiple projects in it, so for example say 10 testing related projects have a dependency on nunit. Currently my solution structure includes folders for Tools and Lib, so maybe the full nunit download is in Tools and just the dll in Lib.
I suppose any package manager (NuGet and OpenWrap being two I'm looking at) needs to create it's own 'known' location for packages. So whereas the old fashioned way of package management, after manually updating my Lib folder, I know every project that had a dependency on nunit just got updated.
But if I update with a package manager, I need to visit each and every project to ensure it is updated and pointing at the same reference, yes? And some dll's may not be found (am thinking unHAddins right now) so you aren't completely liberated from manual package management. Meaning migration to the latest updates isn't done until each and every project is updated by the package manager.
So I'm wondering if my understanding is correct, what the best approach to incorporating package management into a decent sized solution is - for example:
0) add to source control: NuGet 'packages' folder or OpenWrap 'wraps' folder
1) pick a dll (start with one that you beleieve has minimal dependencies)
2) pick a project (ideally with minimal dependencies that might break)
3) if OpenWrap, get the package you want into 'wraps'
4) for each project:
a) add reference to subject dll (manually if OpenWrap, NuGet will add for you)
b) fix compile error as needed
c) run tests
Does that sound right?
Cheers,
Berryl
To answer your questions, no you don't have to do anything with openwrap, all projects import all dependencies within a scope, so the update applies to everything.
I can't answer for the other package managers out there, but in openwrap, you'd add the /wraps folder in source control with the packages that got pulled when you added or updated them. The process would be to first add the package from a remote repository (or create one from your existing assemblies if there's not one available), and remove manually the references from /lib. In OpenWrap, we don't add the references to your csproj, we add them at build time, so if there's already a dependency in /lib, we won't add it. That means you can add all the packages, and remove the references one after the other, running your tests everytime.
Hopefully, this is a temporary problem until all dlls are available as packages, which will happen rather quickly.

TFS and referenced assemblies

I have a project which is under source control using TFS. Actually, I have 2 solution in one TFS Collection. suppose the first solution is called SolutionA, while the second SolutionB. Each solution has it's own project in TFS. Now the problem I have is that, one of SolutionB's project should reference an assembly which is build in SolutionA. So what's best practices to achieve this?
Thanks
You have SolutionA that contains ProjectA, and SolutionB that contains ProjectB:
The two easiest approaches you can use for referencing ProjectA from ProjectB are:
Simply add ProjectA to SolutionB, and then ProjectB can use a project-reference to ProjectA. This means that you share the source code for ProjectA and make an independent build of it from within SolutionB as well as SolutionA. This will slightly slow down your SolutionB build (as you now always build ProjectA in it), but will allow you to make edits to the source code for ProjectA, and treat it as a normal part of SolutionB.
Build SolutionA and use a post-build step (or redirect the output path) to save the resulting ProjectA assembly (and its pdb and xml files, if you want to be able to debug into it) into a shared folder (e.g. C:\Libraries). Then use a file-reference from ProjectB to C:\Libraries\ProjectA.dll. This keeps your SolutionB build fast, and removes the need to have the ProjectA source code lying around, but means that any changes to ProjectA require a double build (first SolutionA to create the .dll and then SolutionB to pick up the changes to the .dll). (You can also opt to check in C:\Libraries to source control so another team could just provide a pre-built binary for ProjectB rather than you having to have anything to do with SolutionA yourself)
To clarify what I mean by Project-references and File-references: In your Solution explorer, right-click on the project's References folder and choose "Add Reference...". In the dialog box that appears, you can choose the tab "Projects" to list the projects in your Solution, and reference one of them (a project-reference). Or choose the "Browse" tab to browse to find a pre-built assembly .dll file (a file-reference)
(You could also install the assembly from ProjectA into the GAC, and then use the add reference dialog to reference it from the ".NET" tab, but IMHO this is a more complicated approach to use as you have more mess to clean up to remove the dll from your system)
There are a couple of options.
If the same team manages both solutions, I would highly recommend just putting them both in the same team project, Or just sharing the same source repository between both projects.
If they are managed by different teams, it might make sense to just give solution b a binary copy of solution a, and update it when a does a release.
If neither of those work, you could add a custom msbuild script in solution b which will get the latest version of solution a from source and build it, before building b. Something like this
My personal opinion is that team projects tend to get over used. I like to just have one team project per team and put all code in the repository there.
Guys, I found a better solution. When I create SolutionB, then I just add ProjectA in SolutionB without branching. To do that, just click File -> Source Control -> Add Project From Source Control.
Voila :-)

Resources