Different git repo for Configure Build Variants - android

I have an app with different version.
But every version have different Git repository.
So please let me know how we can manage that every build variant have different repository.

You should have different tags or branches per version, not different repositories.
From the same repo, you would then use git worktree in order to clone the repo once, but checkout the repo multiple times: see "Multiple working directories with Git?".
That way, you have different folders, each one with a different version of your project.
Since only the name/color/logo are changing, you would need:
one repo with all the common code
one configuration file with the right values for name/color/logo per environment
one way for your code to detect in which environment it is deployed: your code you then pick the right value from the config file.
The point is: one project, one Git repo: See the 12 factors app (in particular, the Config section).

Related

Git parent repository

I am wondering how to manage kind of git "parent" repository.
I started with Android project, where couple of first commits are preparing a project - additional Gradle plugins, dynamic versioning, etc.
Now I would like to externalize it to separate repository, which can be a kind of the template for new projects but also a common place to maintain a project configuration like Gradle and plugins versions, build and sonar configuration, etc. So when I change anything common to all projects, I can easily merge it to all "child" projects.
I thought about few approaches:
fork from the parent project - not really sure, because it is not a real fork
separate projects with remote to parent or parent with remotes to children and pull/push
git submodules it is rather not helpful in this case, or I am wrong?
others?
others...?

What is the Structure/Architecture for White Label Application

I am preparing a white label application (called product later in this post) and I want to set up a very good architecture. This will easily and quickly set up a new client by changing the design, activating features...
I have several servers (dev, pre-prod, prod) so the flavorDimensions server are present in the product and the flavorDimension client is on the client side.
I thought of this solution:
Set up one git per customer and one git for the product.
Clients will have access to the product code by git submodule. This allows me to separate the specific code from my client and the source code of the product.
Git -> Client 1
Submodule -> Product v1
Git -> Client 2
Submodule -> Product v1.2
...
Git -> Product v1.4
But I have a problem how to run it all correctly. The use of flavorDimensions client is hard because I need to make a copy-paste (with gradle) from my submodule to the app module before the build.
The generation of this structure breaks Gradle because its need to be synced every time. (Always Sync Now flag on Android Studio)
So I ask myself, is a good architecture or not ? What do you think ?
Or do you have other ideas and how to implement them?
Thanks for your support.
Hmm interesting take on it.
I have done similar things, but not quite like that. I use flavors for the deltas only. For example, themes, skins, app_icons, and Strings.xml. Maybe a few variations in layout or activities, but do my best to keep it generically served to minimize the maintenance of the code for various customer deployments as each additional flavor slows down the CI process significantly.
However, one key difference in what you are doing is you are not building a platform (aka everyone uses the same code GIT repo and API Server per se, you are building stand alone applications to supply full code and everything else to individual customers.
This sounds like it could be a maintenance nightmare, but if your situation requires that customer's get access to the code base for their product flavor, then I guess it makes sense. Not sure why they would get access to the code though as it is your product you are reskinning for customers right?
At any rate, you aren't asking for me to ask your reasoning haha, you are asking about architectural solutions. So here is my thoughts.
Make a task that copies the respective folders into a new module structure exactly like the modules you have now, but with changes to the package name so that they all slightly differ, then run your GIT push. You can run bash files from Gradle, so you can either write scripts and execute them from relative paths or you can write it directly in your Gradle file itself.
So I would update my Gradle to have separate dependency file like libs.gradle
->Put dependencies in that file like ext.libs {gson:"com.whatever:version"}
->apply from ../libs.gradle
->dependencies { libs.gson, etc..}
So i would assume your build task would do
->Create a new Module from All Source by copying files properly with new names if necessary to rename
->if using maven server, then deploy aar or jar for compiled new module
->Create a new dynamic Gradle file libs.gradle to replace current libs.gradle file that is updated source pointer to deployed artifacts
or created module
->run gradlesync, when complete run assembleRelease, then you can do your git push etc..
All of this can be synchronized and done from terminal and localized into commands. Flavors may not help a ton in this area as they are part of the build process so you kinda need pre build processes which you can create tasks to do pre-build, but the key is the packaging of dependencies and updating your libs.gradle file and making sure that you replace it per flavor. Or if you have fixed flavors you can just make a specific libs.gradle for each flavor and update it based on the compiled dependencies.
I don't know your overall picture, but it is all doable. Hope that helps. Goodluck.

Android Studio - unable to merge from SVN branch

We have decided to follow the process of creating a new SVN branch for every new feature that we add to our mobile app. The ultimate goal behind this is to preserve the history for every single code change (this doesn't happen when we manually copy project folders into SVN instead of creating & merging branches).
My problem is that so far I am unable to merge changes from one branch to another.
I have already referred the following posts without success:
How to merge branch with trunk using SVN in android studio.
Android Studio Update Project: Merge vs Rebase vs Branch Default.
How to merge branch to SVN with Android studio.
How do merge specific svn revisions from branch to trunk in Android Studio 2.0.
Here is what I have tried so far:
I have two feature branches as can be seen below in Tortoise SVN:
I want to merge the changes in the branch Feature_A3 into branch Feature_A2. To do this, I am using the Merge from option in Android Studio's VCS from the A2 working copy:
It then asks me to select the branch to merge from (A3) or configure other branches:
I click on Configure Branches, just to show you the existing branch config:
As you can see, A2 is the Trunk and A3 is the Branch. Is this correct?
It then asks me what part of A3 I want to merge into A2. I select the /src directory (where the relevant changes are present):
It then generously gives me three different ways to perform the merge operation:
I select the third option as it directly gives me the changes I need to merge:
I click on Merge Selected and BAM!!! I get this error every time:
There is no clue as to what the "unresolved conflicts" or "skipped items" are. Why am I getting this error, and what should I do to merge the changes in A3 into A2 ??? Can someone please help ? All answers will be appreciated. Thanks ...
I have been following the official Intellij IDEA documentation below:
Integrating Changes To/From Feature
Branches.
Merging, Deleting, and Comparing
Branches.
Please note that:
Currently I am using Subversion, not Git.
The directory structure of my local working copies is not exactly
identical to that of the SVN repos. Could this be the cause of the error ?
THE ANSWER ...
Thanks to Peter Parker and especially Yoav Aharoni for their valuable feedback. As Yoav correctly pointed out, it was indeed the manner in which the branch locations folder was specified. It needs to be the folder containing the branches, not the branch folders themselves: And as Peter rightly said, checking "Include merged revisions" shows the merged history. I am now able to merge from within the IDE itself, and view the merged history in TortoiseSVN.
NO command line! YAY!!!
However, one last problem is that I am unable to view the merged history in Android Studio (Intellij IDEA) as described in Viewing Merge Sources. Does anyone know how to achieve this in Android Studio?
Phew, haven't used SVN in a while... :)
But from what I can remember Branch locations should be the folder containing your branches folders (and not each individual branch folder).
You see, typically a SVN repo follows a standard naming convention and folder structure:
trunk/
branches/
Feature_A2/
Feature_A3/
tags/
v1.01/
v1.02/
and so on...
trunk is where the main development takes place, and branches are for features, long-term or risky projects, or for different stages (such as QA and pre-prod).
So, as far as I remember, Android Studio expects you to set Branch locations to branches folder. In your case I think it should be http://192.168.0.64/svn/.../Android/Feature.
Also, your trunk is not Feature_A2 - Feature_A2 is just another branch.
Although I can't see the content, I think http://192.168.0.64/svn/.../Android/Development might be your trunk.
Which shouldn't bother you much, since you don't have to merge to your trunk, you can also merge between branches (e.g. merge Feature_A3 into Feature_A2).
So, to recap:
Although not mandatory, I recommend renaming your folders to match the conventions (you can easily do it by right clicking in Tortoise SVN, but only AFTER all teammates commit, otherwise merge will be a HELL for them).
Try setting Branch locations to http://192.168.0.64/svn/.../Android/Feature
And Trunk to http://192.168.0.64/svn/.../Android/Development (only if it indeed contains sources, similar to Feature_A2/3)
Consider "tagging" your releases in a tags folder (it's pretty much just copying the trunk/branch folder to tags, but you have a command for that).
If you do so, you can also add tags folder to Branch locations, that way you'll be able to compare your current source with any previous release (which is handy).
P.S: "unresolved conflicts" error can also mean you have unresolved conflicts (duh :)). Conflicts are are usually created when both you and a teammate change the same lines in file (or if he deletes a file you changed) and you update to get his changes.
SVN won't let you merge until you manually resolve these conflicts/changes.
You can find conflicts in the Version Control tab at the bottom, they'll be mark in red.
(But I don't think that was the problem in your case)
Let me know if that works for you!
I'm not an SVN expert, but I think you will need to change you directory structure. I believe that even though it is just a convention, svn uses the directory structure for merging of branches. So your directory Structure should be:
SVN
/Android
/branches
/production
/featureA2
/featureA3
/tags
/trunk
/IOS
/branches
/production
/featureA2
/featureA3
/tags
/trunk
Even though the TortoiseSVN Repo-browser will allow you to move your directories around, a lot of meta-data is stored on each directory and is used to handle the merge process, so you may have to start your repo again. See the subversion best practices guide and strategories for repository layout for more details on how to setup your repos. All that said, I would hesitate to rely on Android Studio's svn integration to do heavy lifting like merging of branches as (although most things in JetBrains tooling is fantastic) it's handling of SVN leaves a lot to be desired.

Sharing a library or reusing it in another project

Using android studio 1.0 for my project, I plan to code a library module inside it. But I am wondering whether sharing only the library module (for example in its own github repository) is easy : I mean, someone fetching this repository, can integrate it as a library module in its own project easily. Also, does the library module has to define at least an activity, or can it just contain independents classes and resources ?
Of course, I also plan to share the global project on a github repository.
So what is the "safest" and easier way to proceed ?
Apologizing if the question may seem too obvious or bad explained.
The only real way to separate a project into multiple git repositories is through submodules. It's not a bad concept, but what it effectively means is that you have a git repository inside another. One the remote side, they are separate repositories with one being included via submodule.
More information, and the command line tools you'll need to get started can be found at: http://git-scm.com/book/en/v2/Git-Tools-Submodules
Note, there is a lot of hate for submodules, and some of it is earned. It's not intuitive and is often considered an expert Git feature. For that reason, I recommend you read it thoroughly and make sure you understand. Perhaps even throw together a couple of unrelated repositories to play with. BTW, you can have a git repository on your computer anywhere (git init --bare to create it). Then you can clone it anywhere else with git clone file:///<your-path-here> Thus your local and remote are on one computer so you can play/learn without having to create more repositories on git hub or some such.
Since you are using Android Studio, I assume you use Gradle as the build system. With that assumption, below are my answers:
Your library project needs not have Activity, but will need AndroidManifest.xml and a Gradle project layout (src, res folder etc).
If your library project is hosted on Github (or locally outside the root folder of the main project you plan to use it), then you can use Git submodule like lassombra suggested to bring it under root folder of main project.
Once you have the library under the root folder of your main project, you can use Gradle multi-project setup to link them.

Reproducible android builds with git with fast forward merges

I'm looking reproducibility between android system (AOSP) daily builds against repo's collections of git repositories and the impact of using fast-forward merges.
The problem is that when doing daily builds you will get a tip-of-tree while development is happening elsewhere. If HEAD hasn't changed when the change is pushed, it will do a fast-forward merge and time will be re-written. So effectively the physical state of the repository 3 days ago will be different than asking git to go back three days.
The prime solution I can see is to use git with --no-ff to force merge commits. This injects a lot of noise for smaller commits, and seems to be considered bad practice in keeping a clean tree.
The background on this is trying to have reproducibility in an android build environment. For those that don't know, an android build is a collection of disparate git repositories. My ultimate use case is that I want to be able to say, put the code base in the state it was for developers 3 days ago. With fast-forward merges, we lose some critical information on how to correlate between changes on multiple repo projects (ie: git repositories).
As you've noticed, Git doesn't track the state of a branch over time. Two reasonable options are to either set tags for each build or to create a static manifest with the SHA-1s of all checked out commits at the time of the build:
repo manifest -r -o build_20131104.xml
Those files can either be checked into the manifest git and used like e.g.
repo init -u ... -m build_20131104.xml
to reproduce the prior state or you can save the files elsewhere.
Tagging all the gits litters the tag namespace if you're doing a lot of builds (and Git is currently fairly slow with thousands of tags) but is otherwise pretty convenient. Don't forget to tag the manifest git too.

Categories

Resources