Triple-T / gradle-play-publisher

GPP is Android's unofficial release automation Gradle Plugin. It can do anything from building, uploading, and then promoting your App Bundle or APK to publishing app listings and other metadata.
MIT License
4.13k stars 341 forks source link

403 Permission denied :/ #866

Closed ursusursus closed 4 years ago

ursusursus commented 4 years ago

Hi, Im using version 2.8.0.

I'm trying to setup gpp in a project, which was not new. I successfully used gpp without a problem in previous projects. However now I keep getting 403 Permission denied.

I get that it's most likely service account setup wrongly, however I have 0 clues left as what could I have done wrong as I followed your guide, and various guides on internet as well, and visually it checks out but yet


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':generateEditForSkDotTmDotMobile'.
> A failure occurred while executing com.github.triplet.gradle.play.tasks.GenerateEdit$Generator
   > 403 Forbidden
     POST https://androidpublisher.googleapis.com/androidpublisher/v3/applications/sk.tm.mobile/edits
     {
       "code" : 403,
       "errors" : [ {
         "domain" : "global",
         "message" : "The caller does not have permission",
         "reason" : "forbidden"
       } ],
       "message" : "The caller does not have permission",
       "status" : "PERMISSION_DENIED"
     }

All the damn time. I tried creating multiple gcp projects, adding removing them, creating removing service account, givin them Owner role, or admin uiser permissions in Play console... I'm getting desperate

If you could help, I'd be so glad

// Maybe one more clue. In the new redesigned Play console, whever I click 'API Access', I get "Unexpected error bla bla. Try again". So I switched to the classic visuals, and there it appears to be working -- maybe a Google issue afterall?

SUPERCILEX commented 4 years ago

The main thing is that the GCP project from which you export credentials must be linked to your account here: https://play.google.com/console/u/0/developers/api-access. And it has to be given access here: https://play.google.com/console/u/0/developers/users-and-permissions

ursusursus commented 4 years ago

Yes

image

image

image

Seeing anything wrong?

SUPERCILEX commented 4 years ago

Hmmm, that all looks good. Maybe re-generate your credentials for that service account? Could be using outdated ones with GPP. If not, the best would be to contact Play Support. Oh, and the sk.tm.mobile app is in that play account, right?

ursusursus commented 4 years ago

Yea I did contact them because it smells

Btw is there a way I could maybe print out the key that gpp plugin has read in? Maybe the file is bad? Since I keep getting 403s even if I type lorem ipsum into the certificate. Is that expected?

SUPERCILEX commented 4 years ago

Are you using multiple flavors BTW? There was a bug where only one serviceAccountCreds would win. And no, if you're typing invalid json it should crash.

ursusursus commented 4 years ago

Yes im using flavor for backend enviroments, but only deploy "production" to play store

I meant valid json but bogus key content, 403 in my mind means password okay but no permission, rather than invalid password, no?

SUPERCILEX commented 4 years ago

See #842. Can you try upgrading to 3.0? Nah, 403 shouldn't give you any information about the failure. Otherwise you would be able to guess people's service accounts or something.

ursusursus commented 4 years ago

I tried upgrading to 3.0 but no luck

Then I tried the flavors, however I am only using 1 config, since im deploying only one flavor, but I tried it for the hell of it

android {
   playConfigs {
        prodStableRelease {
            track = "alpha"
            serviceAccountCredentials = file("secrets/ci-play-account.json")
        }
    }
}

and now it gives me

> Configure project :foo:app
Warning: Gradle Play Publisher playConfigs object 'prodStableRelease' does not match a variant, flavor, or build type.

FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring project ':foo:app'.
> java.lang.IllegalStateException: No credentials specified. Please read our docs for more details:
  https://github.com/Triple-T/gradle-play-publisher#authenticating-gradle-play-publisher

Is that some clue? Is it not finding the json I provide?

SUPERCILEX commented 4 years ago

Nah, that just means prodStableRelease isn't a valid variant. Maybe it's supposed to be stableProdRelease?

ursusursus commented 4 years ago

well thats odd since it is

image

howver I tried to replace the prodStableRelase with prod, the warning went away, however the exception is still the same (no credentials found)

however if I

        prod {
            track = "alpha"
            def foo = file("secrets/ci-play-account.json").text
            println foo
            serviceAccountCredentials = file("secrets/ci-play-account.json")
        }
    }

I do see the file contents printed correctly ..no clue

SUPERCILEX commented 4 years ago

It'll still crash unless you specify creds for all valid variants. As long as the warning went away then should be good.

BTW, you can use --debug to get a log of each request GPP makes. I don't think that's useful for auth since it shouldn't print creds, but maybe it'll help you.

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

ursusursus commented 4 years ago

Hi, I figured out what the damn issue was. 403 was due to some stupid account geo restrictions on the company gmail account.

When I got over that, I kept getting serviceAccountCredentials not found and I noticed the path was refering to other app in the monorepo. Huh?

Turns out, my project is a monorepo of multiple apps. In the past however it was one app with flavors. When I joined the project I decided it doesn't scale and the other flavor will become its separate app, however I left it as a flavor in the first app as well because of legacy reasons, and just never used / built it.

So, they had the same application id (package name)

It was very confusing since I was running gradle with absolute path like :project1:app:publishProdStableReleaseApk and wtf is the plugin looking at project2 as I mentioned above. I deleted the flavor in the first app and error went away. And everything works now

I now however feels this is a bug in the plugin, since I even noticed it runs :generateSomethingDotPackageBla (cant remember from head) i.e. on root project, no the one im actually running it on

SUPERCILEX commented 4 years ago

Nope, that's how it's supposed to work. There's one global task per app package that generates an edit since otherwise projects would step over each other (the API only allows one active edit per app).

If your build logic is funky, I would recommend removing all the apply plugin bits and going one module at a time to isolate the issue. Sidenote: only the first configured project's credentials will be used for that global task. So if you have different credentials for each app and one of your Gradle modules happens to have the same package as another, the credentials for the second module will be dropped. Basically, there's no use case where two Gradle modules both generate the same app.

ursusursus commented 4 years ago

I don't think it's funky, it's 1 gradle projects with 3 com.android.application modules, where each of these 3 applies the com.github.triplet.play, so I'd assume the google play deploy is local to where its applied to

SUPERCILEX commented 4 years ago

Yeah, that sounds fine. But do they each use different credentials? The easiest way to check if the credential is valid would be to remove the include app1, app2 bits from your settings.gradle[.kts]. That way you can isolate app3 and you'll know for sure if those credentials work.

ursusursus commented 4 years ago

Yes each :app module has its own local credentials. I still don't get why is there a global task

SUPERCILEX commented 4 years ago

Then can you please try isolating the problem to one app only?

The global task is there to join edits for seperate app modules that share the same package. Basically, the API disallows having two edits at the same time, so it's never valid to have two seperate Gradle modules generating their own edits for the same app. We could put the task in the relevant project, but then you would run into race conditions later and weird editDeleted crashes because the projects are stepping over each other. Here, if the issue really is that your project is creating apps with the same package name in different modules, that's catching future bugs.

ursusursus commented 4 years ago

Isolate what? It works now after I removed the unused flavor what duplicated package name for one of the other apps.

Why is there a need to have separate app modules with same package name? And to join them somehow? That's odd to me

SUPERCILEX commented 4 years ago

So your credentials do work if you get rid of the other apps? Then you can fix this two ways:

ursusursus commented 4 years ago

Oh, people share CI credentials between apps? i.e. a single CI user per whole play console?

SUPERCILEX commented 4 years ago

I don't think there's really a preference for sharing one credential vs having one per app (though having a single credential with access to all your apps would also fix the issue). Again, the problem is that separate gradle modules are producing apps with the same package name which doesn't make sense in your context.

ursusursus commented 4 years ago

I understand, but dont understand why is it an issue. I'd not expect a plugin when applied to a given app module to be looking around "outside" by default.

If I were to share credentails id just have them in some root project directory and point each app module plugin there

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.