Skip to content

Change versionCode/versionName when running with --release #1118

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
emiloberg opened this issue Oct 28, 2015 · 24 comments
Open

Change versionCode/versionName when running with --release #1118

emiloberg opened this issue Oct 28, 2015 · 24 comments
Labels

Comments

@emiloberg
Copy link

Hi,

I've been building-beta releasing-building-beta releasing an Android app for a couple of days now. Pretty much every time I build it I forget to update the versionCode and versionName in the AndroidManifest.xml. I get reminded of this then Google's Developer Console rejects my APK because of the versionCode not being larger than the previous version.

An easy way to make a little bit easier for the developers would be to add a prompt for versionCode/versionName in the CLI if the build is run with the --release flag. And let the predefined value be read from the current AndroidManifest.xml. This way the developer will be reminded to update the versionCode/versionName and if s/he doesn't want to it's just an enter stroke away.

If versionCode/versionName is changed then write it back to the AndroidManifest.xml

As tns build could be a part of a larger build script where user input is not possible, a new flag, such as --auto or --quiet, should probably be added as well - skipping the prompt.

@tjvantoll
Copy link
Contributor

Just as an fyi, I’ve also suggested that the Android version code be configured in an app’s package.json under the “nativescript” key. I’m curious what you think about that idea.

@emiloberg
Copy link
Author

Sound idea! And let my proposed prompt update the package.json (which is then used to generate the plist/xml)

@sitefinitysteve
Copy link

I keep running into this as well, very much need a version to be merged with the build

@PanayotCankov
Copy link
Contributor

We are planning to allow app/App_Resources/iOS/Info.plist and app/App_Resources/Android/AndroidManifest.xml to contain these numbers and easily stay in source control.

Also we think to provide two additional options --bundle-version for iOS that can be used with tns build ios --bundle-version 11.1.1 ... and --version-code for Android to be used with tns build android --version-code 111 during the build these will be set in the Info.plist and AndroidManifest.xml in the platforms folder. This should ease CI.

Does this sound sufficient?
Should these update the Info.plist and AndroidManifest.xml in the app/App_Resources?
Would similar switches be useful for CFBundleShortVersionString and versionName?

@rosen-vladimirov
Copy link
Contributor

I would like to see the value populated in app/App_Resources.... This way I'll have (in source control) valid information which is the latest published version.
In case this version is not passed and console is interactive, I believe we should prompt the user to input the version he wants to use.

@emiloberg
Copy link
Author

Sounds like a good start!

Yes the numbers should be bumped and persisted in Info.plist/AndroidManifest.xml. As you always need to bump the numbers before releasing a new version this will be an easy way to keep track of the current version.

And yes, the same for CFBundleShortVersionString/versionName as you need to bump them as well.

@tjvantoll
Copy link
Contributor

I like the App_Resources proposal a whole lot. I prefer configuring these properties in the native file types, and because of that my only concern here is consistency. We already allow you to specific an app id in your package.json under the "nativescript" key, so putting the version number in Info.plist / AndroidManifest.xml seems inconsistent.

Therefore we may want to consider moving app id out of the package.json file, and just let you configure your CFBundleIdentifier and package in the native files instead. I think it’s fine as long as the starting templates spit out some good default values. I’d love to see the other things I lay out in #478 be supported through this approach as well.

Also we think to provide two additional options --bundle-version for iOS that can be used with tns build ios --bundle-version 11.1.1 ... and --version-code for Android to be used with tns build android --version-code 111 during the build these will be set in the Info.plist and AndroidManifest.xml in the platforms folder. This should ease CI.

I’ll just note that I personally don’t have a need for this workflow. I just want to change the version numbers in my Info.plist and AndroidManifest.xml in App_Resources. That being said I’m not opposed to these options being added to the CLI as a nicety.

@sitefinitysteve
Copy link

I dont suppose in the package.json we could do like

"version": {
   "ios": "2.0.0",
   "android": "2.2.0",
},

Or if not seperated, they both use the same version number?

"version": "2.1.1",

I personally would not like\find the need to manually set the version on a build with a parameter... sure it saves me time opening xcode to change it, but fundamentally it's the same thing.

@PanayotCankov
Copy link
Contributor

@tjvantoll: I wanted these for automation because I dislike sed in the Jenkins builds but need its packages to be submit-able in App/Play stores (e.g. each build should print different numbers). If I am building manually I'd bump the numbers in app/App_Resources/... like you would.

@sitefinitysteve: We can. We do so for CFBundleIdentifier already. But I am not sure what's the best approach here. For JS devs setting these in package.json would be somewhat more convenient but then we will end with two different places where you can set them. Also it may frustrate native native developers moving to {N}. P. S. The build numbers for iOS and Android diverge extremely fast.

@tjvantoll
Copy link
Contributor

@PanayotCankov Ah gotcha, that makes a lot of sense. No one likes sed 😛

@sitefinitysteve I would argue that it’s not the same because you don’t have to go into Xcode at all. You just need to open up a pre-provided file and increment a value. I personally think we do ourselves a disservice if we try to abstract away iOS and Android too much. Developers are going to do Google searches and find existing iOS/Android guides and advice, and we stand to benefit from that. We can easily allow version to be configured in your package.json, but we can’t realistically extend that to the tens and hundreds of things people will want to configure for their iOS/Android apps, so for consistency’s sake I prefer sticking with the native file types. That’s also why I’d like to see app id moved out as well 😃

@sitefinitysteve
Copy link

I have been convinced!... So why bother with the one in package.json at all then i suppose.

@ligaz
Copy link

ligaz commented Feb 29, 2016

We are planning on providing a publish command (#1172) that can ease this process. Regarding changing other properties our current thinking aligns well with what @tjvantoll have outlined. More on the subject here.

@toddanglin
Copy link

Revisiting this...

Since NativeScript is really created for the JS dev (versus the "native developers"), I think it feels more intuitive to control these basic app configuration values in the package.json. As Steve said, I like the option of setting the value in one place to manage all of my target platforms (could be more than iOS/Android in the future).

Steve's proposal for version numbers in package.json is great.

If we want to reduce confusion, we could change the default value in Info.plist/AndroidManifest.xml to a clear variable placeholder (like ${app_version}) that gets replaced at build time.

If someone REMOVES this variable from the native config files, then they can set the values directly and package.json will NOT be used to change version numbers.

Thoughts?

@jacargentina
Copy link

I've implemented this for my own project https://github.com/jacargentina/nativescript-dev-version

@dtopuzov
Copy link
Contributor

@jacargentina thanks for the solution.

In general it looks there is a need to pass extra params to build command.
Closing in favor of #2548

@toddanglin
Copy link

@dtopuzov It's not clear to me how #2528 directly relates to the issue discussed in this thread.

Based on my reading of #2528, there is a need for a solution to pass additional/arbitrary parameters with CLI commands to support development workflows that need to alter start-up configurations in different environments (like 'test', 'demo', 'staging', etc).

This thread was more about 1) the ability auto-change version/build numbers when you run a CLI command, and 2) defining app version numbers in the package.json file instead of the separate iOS/Android config files.

Do you see the solutions being discussed in #2528 as addressing the challenges raised in this thread?

@dtopuzov
Copy link
Contributor

Hi @toddanglin

Changing build version, changing environment, changing some config, all those look to be cases when you need something custom and may be custom flags are the solution for this problem.

Reopen, since changing build version is common case and may be you are right that we should provide such mechanism out of the box (not via custom flags).

@dtopuzov dtopuzov reopened this May 23, 2017
@speigg
Copy link

speigg commented Jun 6, 2017

I would like to see the standard package.json version property supported for setting the version / build numbers for both iOS & android, so that they can be incremented together (in whatever manner makes sense for converting a valid semver to an appropriate convention for each platform).

Specifically, being able to use the standard version property (rather than placing it in a nativescript namespace) allows it to work seamlessly with existing tools for managing version numbers, like npm version patch or https://github.com/conventional-changelog/standard-version. There isn't a good reason, imo, why version numbers for iOS vs android builds should diverge, but if there is no version value specified in package.json, we can just fallback to current behavior and let the versions be managed individually.

@toddanglin
Copy link

I still like @sitefinitysteve's proposal for adding flexibility to separately version iOS and Android builds (as you may evolve them slightly differently, even within the same shared code/app).

To recap his proposal, in package.json you should be able to version BOTH iOS and Android versions of an app using the standard version property:

"version": "1.0.0", 

If you need do need to separately version iOS and Android (say you publish a major update for an app for iOS before Android updates are ready), you should be able to provide version numbers for each platform:

"version": {
   "ios": "2.0.0",
   "android": "1.8.1"
}

In both cases, the values in package.json are used to automatically update the versions in Info.plist/AndroidManifest.xml.

@terreb
Copy link

terreb commented Aug 30, 2017

Any updates here?

@jpgilchrist
Copy link

I have noticed that this functionality is incorporated into sidekick. You can update a single version and it updates both ios/android. However, I would like this functionality to be available by a script to incorporate into various CI/CD cycles.

@yahyaKacem
Copy link

Any updates here?

@Yura13
Copy link

Yura13 commented Jan 22, 2020

When this feature will be released?

@pfumagalli
Copy link
Contributor

I have a little after-prepare hook that updates the Info.plist and AndroidManifest.xml according to what I specify in package.json.

Basically, my Info.plist and AndroidManifest.xml in App_resources/... contain the strings __VERSION__ and __BUILD__, which gets replaced before compiling:

I put this in hooks/after-prepare/version.js

const fs = require('fs')
const shell = require('shelljs')

module.exports = function($logger, $projectData) {
  const platformsDir = $projectData.platformsDir
  const projectName = $projectData.projectName

  const version = $projectData.packageJsonData.version
  const [ major, minor, patch ] = version.split('.').map((v) => parseInt(v))
  const build = ((major * 100000000) + (minor * 100000) + patch).toString()
  const infoPlist = `${platformsDir}/ios/${projectName}/${projectName}-Info.plist`
  const androidManifest = `${platformsDir}/android/app/src/main/AndroidManifest.xml`

  $logger.info(`Updating version to ${version} (build=${build})`)

  for (const file of [ infoPlist, androidManifest ]) {
    if (fs.existsSync(file)) {
      $logger.debug(`Replacing "__VERSION__" with "${version}" in ${file}`)
      $logger.debug(`Replacing "__BUILD__" with "${build}" in ${file}`)
      shell.sed('-i', /__VERSION__/, version, file)
      shell.sed('-i', /__BUILD__/, build, file)
    }
  }
}

If someone finds it useful, feel free to steal/modify.

PS. shelljs is needed, but it's already a nativescript dependency, so, no extra downloads needed, tested on 7.x.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests