Skip to content
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

Use apksigner to sign Android APK, bump up major version #7544

Merged
merged 3 commits into from
Jun 22, 2018

Conversation

yacaovsnc
Copy link
Member

@yacaovsnc yacaovsnc commented Jun 21, 2018

jarsigner is no longer the right tool to sign APK files. Update the task to use apksigner.

This was reported in issue #4783.

Tested on Hosted, Hosted 2017 and macOS pool. It's able to locate the apksigner tool and use it to sign.

@brcrista
Copy link
Contributor

What have you done to test?

@yacaovsnc
Copy link
Member Author

Reformatting, changed a few files names, cleaned up some tests, removed unused fields, etc... There were quite a lot of changes went into tests. -_-

@brcrista
Copy link
Contributor

I mean, what have you done to test the change? :)

@lkillgore
Copy link
Contributor

Are you removing AndroidSigningV2? If so, this PR could be more legible if git was set-up as 'moves' and 'renames' instead of 'additions'.

@yacaovsnc
Copy link
Member Author

image

UI didn't really change. I added a field to override the location of apksigner, this is to make it consistent with zipalign tool.

// add * in search as on Windows the tool may end with ".exe" or ".bat"
const toolsList = tl.findMatch(tl.resolve(androidHome, 'build-tools'), tool + '*', null, { matchBase: true });

if (!toolsList || toolsList.length === 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dead code -- toolsList.length === 0 implies !toolsList

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need some refreshers on dynamic languages... -_- Wouldn't you hit NRE (or equivalent of it in javascript) if you don't check for !toolsList?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No you're right. Just if (!toolsList) because an empty list is falsy

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

empty list isn't falsy in my testing:

 a = 0
 b = []
 if (!a) { console.log("a is false") }
 if (!b) { console.log("b is false") }

prints a is false

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All right, I changed it back to be explicit. Safety first. :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ughhhh @hashtagchris you're right: https://developer.mozilla.org/en-US/docs/Glossary/Truthy

I was confused because:

image

And because [] is falsy in Python:

image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And of course '' is still falsy, which makes no sense
image

"required": false,
"visibleRule": "apksign = true",
"groupName": "apksignerOptions",
"helpMarkDown": "Optionally specify the location of the apksign executable used during signing. This defaults to the apksign found in the Android SDK version folder that your application builds against."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the name of the tool apksigner? https://developer.android.com/studio/command-line/apksigner

"name": "apksignerLocation",
"aliases": ["apksignerFile"],
"type": "string",
"label": "Apksigner location",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the label say "APK signer location?"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tool is called 'apksigner', maybe I shouldn't capitalize the first letter?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so, follow same pattern as in the android docs.


// if the tool path is not set, let's find one (anyone) from the SDK folder
if (!apksigner) {
apksigner = findAndroidTools('apksigner');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we not want to fall back to JAR signing if the APK signer tool can't be found?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want to fall back to JAR signing especially since it has been a year since apksigner switch was made. I like we are updating the major version of the task, so customers who want to use jarsigner can use previous version.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. This is worth considering. This tool came out with version 24 (Android 7.0). https://developer.android.com/about/dashboards/ Not many use this, yet. Developers may not have updated their privately hosted agents either, and want the same definition to work on both.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's ok not to fall back if JAR signing is considered deprecated now. I just wanted to know what the debate was.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good to add in the "releaseNotes" that if you are on Android 7 or higher, you should use V3. We could update the task description on V2 as well to use V3. I am assuming apksigner would work for older android versions as well if the tool is available and used.

import * as Q from 'q';
import * as tl from 'vsts-task-lib/task';

const findAndroidTools = (tool: string): string => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think findInAndroidTools or findAndroidTool better describes what this function is doing. Also, would it make more sense to return a tl.ToolRunner instead of a string?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to findAndroidTool.

@yacaovsnc
Copy link
Member Author

@lkillgore not removing the v2 folder, the current recommendation is to keep all major versions side by side according to @stephenmichaelf.

const findAndroidTools = (tool: string): string => {
const androidHome = tl.getVariable('ANDROID_HOME');
if (!androidHome) {
throw tl.loc('AndroidHomeNotSet');
Copy link
Contributor

@lkillgore lkillgore Jun 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to get in the habit of using this pattern: throw new Error(tl.loc('AndroidHomeNotSet'). That way we get a better stack trace.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Several places in this file could use that improvement.

@yacaovsnc
Copy link
Member Author

@brcrista I uploaded this task to my personal account, and used it to sign APKs. Only tested in Hosted VS2017 for now, need to test on other OSes.

Copy link
Contributor

@madhurig madhurig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you test on hosted win, mac and linux vms? I would expect this to work on windows and mac.

@@ -0,0 +1,21 @@
import fs = require('fs');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

switch to import * as fs syntax?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(modules imported with import-from are treated as readonly, while import-require basically gives you a JS object)

"demands": [
"JDK",
"AndroidSDK"
],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add "releasenotes" to explain what changed in this version. https://github.com/Microsoft/vsts-tasks/blob/master/Tasks/XcodeV5/task.json#L17

@stephenmichaelf
Copy link
Member

stephenmichaelf commented Jun 21, 2018

@yacaovsnc @lkillgore Yes they both live side by side. I just realized... in the future it may be easier to do a branch with the new task and then a branch off of that with the changes. Have had this problem with a few other tasks that bumped major too. :)

@stephenmichaelf
Copy link
Member

Also whenever you get a chance, we are generally moving away from Typings since it's deprecated and moving to @ types.

@madhurig
Copy link
Contributor

Only issue I have with @ types is VSCode seems to not recognize them or I am missing a VSCode/plugin update

@brcrista
Copy link
Contributor

@madhurig it works fine for me, I used @ types for the Python tasks. Shouldn't need a plugin


async function run() {
let keystoreFileId: string;
let secureFileHelpers: secureFilesCommon.SecureFileHelpers;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a 'nit', but I don't see why these are scoped outside the if-block, and not 'const'.

@yacaovsnc yacaovsnc merged commit d28dc61 into master Jun 22, 2018
@yacaovsnc yacaovsnc deleted the users/yacao/apksigner branch June 22, 2018 13:24
@ckrempp91
Copy link

When will this be available for use?

@brcrista
Copy link
Contributor

This was released several months ago. Make sure you have updated to V3 of the task.

@ckrempp91
Copy link

Ok, the documentation is still referring to jarsigner here: https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/build/android-signing?view=vsts, was this made available for TFS 2017, or just TFS 2018 & Devops?

@brcrista
Copy link
Contributor

This would only be in on-prem versions that shipped after this PR was completed.

@brcrista
Copy link
Contributor

@ckrempp91 I checked on this and the only on-prem release we've shipped was TFS 2018 Update 3, which was just a bug fix release. So this will go with Azure DevOps Server 2019 (TFS 2019).

@ckrempp91
Copy link

Thank you for the update @brcrista!

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

Successfully merging this pull request may close these issues.

7 participants