ittybittyapps / appstoreconnect-cli Goto Github PK
View Code? Open in Web Editor NEWAn easy to use command-line tool for interacting with the Apple AppStore Connect API
License: MIT License
An easy to use command-line tool for interacting with the Apple AppStore Connect API
License: MIT License
Modify a beta group's metadata, including changing its Testflight public link status.
As a ...
I want ...
So that ...
Covering this API.
Provide design example, screenshot, text input/output etc
GIVEN ...
WHEN ...
THEN ...
Describe what is out of scope
As a user
I want to be able to fetch the details of a user by email address
So that I can see details of this user, their roles and the apps they can see.
Covering this API.
As a user
I would like to be able to run appstoreconnect-cli on Linux
So that I can run it on Linux CI hosts
Get tool build/running on Linux so users don't pay 10x for GitHub macOS runners.
We can then also build Docker based GitHub actions based on this tool.
Find and list certificates and download their data.
As a user
I want list and/or download certificates
So that I can inspect them
Covering this API.
asc certificates list --filter-serial XXYYZZ --sort <sort> --filter-type <type> --filter-display-name <name> --limit 100 --download-path ./path
Output:
"๐ฅ Certificate '\(certificate.name)' downloaded to: \(path/serial.cer)"
SerialNumber | Name | Display Name | Platform | Type | Expiration Date |
---|---|---|---|---|---|
XXXYY | Name | Something | iOS | ios_development | Date |
GIVEN I provide a valid input without a --download-path
WHEN I issue a list command
THEN the certificates I have are listed.
GIVEN I provide valid input with a --download-path
WHEN I issue a list command
THEN the certificates I have are listed
AND the certificates are saved to the specified path.
GIVEN I provide a invalid input
WHEN I issue a list command
THEN I receive an appropriate error message.
GIVEN I provide valid inputs to the list command
WHEN the API fails
THEN I receive an appropriate error message.
Get a list of prerelease versions for all apps.
As a user
I want to list pre-release versions of my application
So that I can inspect the details
Covering this API.
asc testflight prereleaseversion list --filter-app <bundleId> --filter-build-processing-state <states...> --filter-builds-expired <bool?> --filter-platform <platforms...> --filter-version <versions...> --limit <n> --sort <order>
GIVEN ...
WHEN ...
THEN ...
Describe what is out of scope
Enable a capability for a bundle ID.
As a user
I want enable a capability on a specific bundle ID
So that my app can use that capability
Covers this API.
asc capability enable bundleId capabilityType <capability configuration options based on type>
GIVEN ...
WHEN ...
THEN ...
As a user
I want to be able to list all the apps on my App Store connect account.
So that I can review them.
Covering API.
We have not yet implemented GetBetaTesterInfoCommand
.
As a user
I want get all the information relating to a beta tester
So that so that I can view it.
This should cover all the features of the API.
However we should use the beta tester's email address to find them rather than their opaque resource ID as is required by the API. So it might be easier to use the list API with a filter on email rather than call the Read Beta Tester Information
API. I'm pretty sure the information returned is the same.
We should support --limit-apps
, --limit-builds
, --limit-beta-groups
options to control the number of fetched apps, builds and betaGroups.
asc testflight betatester info [email protected]
Output:
First Name | Last Name | Invite Type | Apps | Beta Groups | |
---|---|---|---|---|---|
[email protected] | Joe | Example | com.iba.app1 | Friends of Friends |
In YML and JSON formats more detailed data for the App and BetaGroups could be displayed based on the data fetched we should not be restricting the field set fetched.
GIVEN a tester exists with the email address [email protected]
WHEN I specify the email address [email protected]
THEN the data for the user with the email address [email protected]
should be displayed
GIVEN a tester does not exist with the email address [email protected]
WHEN I specify the email address [email protected]
THEN an error message Beta Tester for specified email address not found.
should be displayed on stderr
, no output should be sent to stdout
.
GIVEN a tester exists with the email address [email protected]
and has 10 associated apps
WHEN I specify the the arguments [email protected] --limit-apps 5
THEN only 5 apps should be displayed in the list of apps the user has associated with them.
As a user
I want to be able to synchronise AppStore Connect users with a file
So that I can keep my user configuration in source control and practice infrastructure-as-code principles with AppStore Connect.
I should be able to have a file that contains the canonical information about users in App Store Connect.
Ideally this command should not require state. It would consider the input files as the canonical source of information and push that into the AppStore Connect API.
You would have a file (yaml, csv, json) on disk that would have all the details of users, their roles and the apps they should have access to. If the CLI had the right level of permissions on the account it could create/delete/modify all users.
--dry-run
option that only prints what would happen and doesn't actually take action on the AppStore Connect API.
๐จNote that this sync
function should never delete users with the ACCOUNT_HOLDER
role. It probably can't anyway but it shouldn't try.
Get information about a specific app.
As a ...
I want ...
So that ...
Covering this API.
Provide design example, screenshot, text input/output etc
GIVEN ...
WHEN ...
THEN ...
Describe what is out of scope
The limit option for users list doesn't work. It returns the entire list.
Steps to reproduce the behavior, provide an example of the command line issued:
swift run asc users list --limit 5
Should return only 5 users if the limit is set as 5
It returns the entire list
Revoke a lost, stolen, compromised, or expiring signing certificate.
As a user
I want to revoke a compromised certificate
So that so that it can no longer be used to sign apps
Covering this API.
asc certificates revoke XCYZ ABCD EFGH
Output:
๐ฎ Certificate `XCYZ` revoked.
๐ฎ Certificate `ABCD ` revoked.
๐ฎ Certificate `EFGH ` revoked.
GIVEN I provide a valid input
WHEN I issue a revoke command
THEN the certificates I specified are revoked.
GIVEN I provide some invalid input (eg, one of the serials I provide is invalid)
WHEN I issue a revoke command
THEN then NO certificates are revoked and I receive an appropriate error message.
We don't have a LICENSE.md
file.
Create a license file with the MIT License.
At the moment we don't have any linting being performed during build.
Configure the build process to run SwiftLint with appropriate rules.
We want to be pretty strict with our rules so we have a consistent looking codebase.
Get information about a certificate and download the certificate data.
As a user
I want to display information about a certificate and optionally download the certificate file
So that I can inspect the certificate
Covering this API.
asc certificates read XXYYZZ --certificate-output ./file.cer
Output:
"๐ฅ Certificate '(serial)' downloaded to: (certificateOutput)"
SerialNumber | Name | Display Name | Platform | Type | Expiration Date |
---|---|---|---|---|---|
XXXYY | Name | Something | iOS | ios_development | Date |
GIVEN I provide a valid input without --certificate-output
WHEN I issue a read command
THEN the certificate's information is displayed (as above).
GIVEN I provide valid input with --certificate-output
WHEN I issue a list command
THEN the certificate's information is displayed and the certificate data is written to the specified file.
GIVEN I provide a invalid input
WHEN I issue a list command
THEN I receive an appropriate error message.
GIVEN I provide valid inputs to the list command
WHEN the API fails
THEN I receive an appropriate error message.
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
10:e6:fc:62:b7:41:8a:d5:00:5e:45:b6
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Organization Validation CA - SHA256 - G2
Validity
Not Before: Nov 21 08:00:00 2016 GMT
Not After : Nov 22 07:59:59 2017 GMT
Subject: C=US, ST=California, L=San Francisco, O=Wikimedia Foundation, Inc., CN=*.wikipedia.org
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
00:c9:22:69:31:8a:d6:6c:ea:da:c3:7f:2c:ac:a5:
af:c0:02:ea:81:cb:65:b9:fd:0c:6d:46:5b:c9:1e:
9d:3b:ef
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Agreement
Authority Information Access:
CA Issuers - URI:http://secure.globalsign.com/cacert/gsorganizationvalsha2g2r1.crt
OCSP - URI:http://ocsp2.globalsign.com/gsorganizationvalsha2g2
X509v3 Certificate Policies:
Policy: 1.3.6.1.4.1.4146.1.20
CPS: https://www.globalsign.com/repository/
Policy: 2.23.140.1.2.2
X509v3 Basic Constraints:
CA:FALSE
X509v3 CRL Distribution Points:
Full Name:
URI:http://crl.globalsign.com/gs/gsorganizationvalsha2g2.crl
X509v3 Subject Alternative Name:
DNS:*.wikipedia.org, DNS:*.m.mediawiki.org, DNS:*.m.wikibooks.org, DNS:*.m.wikidata.org, DNS:*.m.wikimedia.org, DNS:*.m.wikimediafoundation.org, DNS:*.m.wikinews.org, DNS:*.m.wikipedia.org, DNS:*.m.wikiquote.org, DNS:*.m.wikisource.org, DNS:*.m.wikiversity.org, DNS:*.m.wikivoyage.org, DNS:*.m.wiktionary.org, DNS:*.mediawiki.org, DNS:*.planet.wikimedia.org, DNS:*.wikibooks.org, DNS:*.wikidata.org, DNS:*.wikimedia.org, DNS:*.wikimediafoundation.org, DNS:*.wikinews.org, DNS:*.wikiquote.org, DNS:*.wikisource.org, DNS:*.wikiversity.org, DNS:*.wikivoyage.org, DNS:*.wiktionary.org, DNS:*.wmfusercontent.org, DNS:*.zero.wikipedia.org, DNS:mediawiki.org, DNS:w.wiki, DNS:wikibooks.org, DNS:wikidata.org, DNS:wikimedia.org, DNS:wikimediafoundation.org, DNS:wikinews.org, DNS:wikiquote.org, DNS:wikisource.org, DNS:wikiversity.org, DNS:wikivoyage.org, DNS:wiktionary.org, DNS:wmfusercontent.org, DNS:wikipedia.org
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Subject Key Identifier:
28:2A:26:2A:57:8B:3B:CE:B4:D6:AB:54:EF:D7:38:21:2C:49:5C:36
X509v3 Authority Key Identifier:
keyid:96:DE:61:F1:BD:1C:16:29:53:1C:C0:CC:7D:3B:83:00:40:E6:1A:7C
Signature Algorithm: sha256WithRSAEncryption
8b:c3:ed:d1:9d:39:6f:af:40:72:bd:1e:18:5e:30:54:23:35:
...
Delete a beta group and remove beta tester access to associated builds.
As a ...
I want ...
So that ...
Covering this API.
Provide design example, screenshot, text input/output etc
GIVEN ...
WHEN ...
THEN ...
Describe what is out of scope
Find and list beta testers for all apps, builds, and beta groups.
As a user
I want to be able to list all the beta testers associated with my apps
So that so that I can view them.
Covering this API.
asc testflight betatesters list --filter-email <email address patterns> --filter-firstname <firstnames> --filter-lastname <lastnames> --filter-invite-type <invite type> --filter--fliter-apps <bundle ids> --filter-beta-groups <beta group list> --limit <n> --sort <sort options>
Output:
Email Address | First Name | Last Name | Invite Type | Apps | Groups |
---|---|---|---|---|---|
[email protected] | Me First | Last | public_link | App1, App2, App3 | Group 1, Group2 |
GIVEN ...
WHEN ...
THEN ...
Every cool open source project has a screenshot or gif that demonstrates how to use it.
Create an animated gif of the tool in use for prominent positioning in our README.
See example:
Download finance reports filtered by your specified criteria.
As a user
I want to download my app's financial reports
So that so that I can analyse the data offline
Covering this API.
asc reports financial regionCode reportDate reportType vendorNumber outputFilename
GIVEN I specify valid input
WHEN I issue the command
THEN data is written to the specified outpoutFilename
GIVEN I specify invalid input
WHEN I issue the command
THEN I receive an appropriate error message
GIVEN I issue the command
WHEN the API fails
THEN I receive an appropriate error message
GIVEN I issue the command
WHEN no data is available
THEN I receive an appropriate error message
HTTPClient.deviceUDIDResourceId(matching:) will throw notUnique
when nothing matches.
Should we throw a different error or no error at all?
Originally posted by @adamjcampbell in #75
To increase the flexibility of the tool it should support reading and writing data from CSV files. Examples of data that would make good use of CSV:
As a user
I want to be able to read certain input as CSV data.
So that I can use tools like Numbers or Excel to make it easier maintain that data.
There is already an implementation of Codable for CSV that we can take advantage of.
GIVEN I have am issuing a command
WHEN I specify the option --output-format csv
THEN the resulting output should be formatted as CSV
GIVEN I have am issuing a command such as appstoreconnect-cli users sync
WHEN I specify the input file ending in .csv
THEN the input file is parsed as CSV data.
Get a specific beta group and display its information.
As a ...
I want ...
So that ...
Covering this API.
Provide design example, screenshot, text input/output etc
GIVEN ...
WHEN ...
THEN ...
Describe what is out of scope
We need to be able to invite beta testers to an organisation and give them access to apps.
As a User
I want to be able to invite beta tester become testers of specific apps in my organisation
So that they can install those apps on their devices
Example command:
asc testflight betatesters invite [email protected] Joe Example com.iba.app1 --groups "Group 1" "Group 2"
The above command invites the user to be a tester of an app and adds them to two groups.
First Name | Last Name | Invite Type | Apps | Beta Groups | |
---|---|---|---|---|---|
[email protected] | Jo | Example | com.iba.app1 | Group 1, Group 2 |
GIVEN there is no existing beta tester with the email address [email protected]
WHEN I issue the command asc testflight betatesters invite [email protected] com.iba.app1 --groups "Group 1" "Group 2"
THEN the specified user is invited and the relationships with the specified app and groups are established
AND the details of the invited user are displayed to stdout
GIVEN there is no existing "Group 1" beta group for app com.iba.app1
WHEN I issue the command asc testflight betatesters invite [email protected] com.iba.app1 --groups "Group 1" "Group 2"
THEN an error is displayed No Beta Group "Group 1" exists for application with Bundle ID "com.iba.app1".
to stderr
and there is no output to stdout
.
As a user
I want to be able to register, modify or delete Bundle IDs,
So that the I can manage bundle IDs easily.
Covering this API.
Remove a specific beta tester from one or more beta groups, revoking their access to test builds associated with those groups.
As a user
I want remove an existing beta tester from beta groups
So that so I can manage user access
Covering this API.
asc testflight betatesters removegroup emailAddress groups...
asc testflight betagroup removeuser emailAddresses...
GIVEN ...
WHEN ...
THEN ...
Cloning the codebase and running swift build
currently fails
You must also generate the xcode project and build in xcode project
Finally building from the command line once more
Also creation of a bin
directory allows the binary to be copied correctly (this is done from a scheme post action)
Given that this tool is likely to be run from CI or by a user interactively we will need multiple ways of feeding authentication credentials (API key).
We should support specifying the credentials via the environment (to support CI).
Possible environment keys:
APPSTORE_ISSUER_ID
APPSTORE_KEY_ID
APPSTORE_KEY
We can also read the this from some sort of ~/.appstoreconnect-cli/auth.{yml,json}
file. We should ensure that this file and directory is mode 0600
and owned by the running user for security sake.
We could also support the behaviour that altool
does for command-line arguments, eg:
--apiKey <api_key> API Key. Required for JWT authentication while using
validation, upload, and notarization. This option will search the following
directories in sequence for a private key file with the name of
'AuthKey_<api_key>.p8': './private_keys', '~/private_keys', '~/.private_keys',
and '~/.appstoreconnect/private_keys'.
--apiIssuer <issuer_id> Issuer ID. Required if --apiKey is specified.
Download sales and trends reports filtered by your specified criteria.
As a user
I want to download my app's sales and trend reports
So that so that I can analyse the data offline
Covering this API.
asc reports sales frequency reportDate reportType reportSubType vendorNumber outputFilename --version version
GIVEN I specify valid input
WHEN I issue the command
THEN data is written to the specified outpoutFilename
GIVEN I specify invalid input
WHEN I issue the command
THEN I receive an appropriate error message
GIVEN I issue the command
WHEN the API fails
THEN I receive an appropriate error message
GIVEN I issue the command
WHEN no data is available
THEN I receive an appropriate error message
This tool could be used by a world wide audience. Our displayed output should at least support localisation.
As an international user
I want output to be in my default locale
So that so that I don't need to know English in order to use the application effectively
The actual translation of messages.
As a user
I want to be able to invite users to my team
So that they can take a specific role in my development team for specific apps
Covering this API
As a user
I want to be able to create a beta tester assigned to a group, a build, or an app by their email address, first and last name,
So that he/she can receive the invitation, get the access and download the app from TestFlight
Covering this API.
Find and list beta groups for all apps.
As a User
I want to list my beta groups
So that I can see what groups have been configured
Covering this API.
asc testflight betagroup list
Input:
There are multiple filters that can be applied, we should choose the most relevant ones for initial release.
Output:
App Bundle ID | App Name | Group Name | Is Internal | Public Link | Public Link Enabled | Public Link Limit | Public Link Limit Enabled | Creation Date |
---|
GIVEN ...
WHEN ...
THEN ...
Describe what is out of scope
Disable a capability for a bundle ID.
As a use
I want disable a capability for a bundle ID
So that my app no longer can use that capability.
Covering this API.
asc capability disable bundleId capabilityType
GIVEN ...
WHEN ...
THEN ...
We currently call directly into AppStoreConnect_Swift_SDK
and couple ourselves to it by directly making use of it from our commands
We mix and match whether we use AppStoreConnect_Swift_SDK
models (with extensions) or if we translate into our own Models
It's reaching the point where we want our own consistent Model layer and to abstract the knowledge of AppStoreConnect_Swift_SDK
away from our commands
AppStoreConnect_Swift_SDK
and translates the library model types to our model typesWe should structure our models with consideration for table formats, some models we use are quite nested
If we are to support pretty output tables and csv
we need a flat structure that can print models row by row
#24
This work is needed to output CSV correctly as CSVDecoder does not support types that are nested more than two levels.
Update the configuration of a specific capability.
As a user
I want modify a capability on a specific bundle ID
So that my app can use that capability
Covering this API.
asc capability modify bundleId capabilityType <capability settings>
GIVEN ...
WHEN ...
THEN ...
At the moment we're not performing any form of CI, we should.
Set up GitHub Actions to build the project (and run unit tests) for Pull Requests.
If we could get this project running on Linux we could use Linux GitHub Actions agents. macOS agents will be free when this project is public/Open Source. For private repos they cost 10x as much as Linux hosts.
This project needs a logo. Every cool open source project needs a logo.
Create a cool logo for placement in the README
.
Some examples of open source projects that have logos:
We currently do not have a contributing guide for the project with guidance on how we expect people to contribute.
Define clear well articulated CONTRIBUTING.md
and CODE_OF_CONDUCT.md
files for the project.
A good way to start this would be to take inspiration from some good documentation from another popular open source project.
Every cool macOS command line tool needs to be installable with brew.
Create a homebrew formula for appstoreconnect-cli
.
See other projects that have formula for guidance.
Get a specific beta tester.
As a user
I want to get the information of a specific beta tester
So that I can view it
Covering this API.
asc testflight betatesters read emailAddress
Output:
Email Address | First Name | Last Name | Invite Type | Apps | Groups |
---|---|---|---|---|---|
[email protected] | Me First | Last | public_link | App1, App2, App3 | Group 1, Group2 |
GIVEN ...
WHEN ...
THEN ...
We have issue #12, and creating beta testers is one of the main features of AppStoreConnect API.
But it can't cover all the use cases, and we want to do more about TestFlight testers
As a user
I want to be able to
So that I can have better management of all the beta testers
Covering APIs
list
to see a list of all the beta testers of an app, by inputting app's bundleId
This Issues not relevant to Beta Groups, we will have another issue for Beta Groups
Currently none of our commands support paging.
Steps to reproduce the behavior, provide an example of the command line issued:
That all pages of data are fetched.
On the first page of data is fetched.
Get information about a specific prerelease version.
As a ...
I want ...
So that ...
Covering this API
Provide design example, screenshot, text input/output etc
GIVEN ...
WHEN ...
THEN ...
Describe what is out of scope
Get a list of builds of a specific prerelease version.
As a ...
I want ...
So that ...
Covering this API.
Provide design example, screenshot, text input/output etc
GIVEN ...
WHEN ...
THEN ...
Describe what is out of scope
Remove a beta tester's ability to test all apps.
As a user
I want to be able to delete beta testers
So that so that they can't see my apps anymore
Covering this API.
asc testflight beta-tester delete emailAddress
GIVEN I have the email address of a beta tester
WHEN I issue the command
THEN the beta tester is deleted.
GIVEN I supply the email address of someone who is not a beta tester
WHEN I issue the command
THEN an appropriate error message is displayed
As a user
I want to be able to list all the users registered on my App Store connect account
So that I can review them.
The output should be in a tabular format. Using something like https://github.com/scottrhoyt/SwiftyTextTable or https://github.com/cfilipov/TextTable (pick the most suitable, or another).
The output should also be able to be rendered for easy consumption by other tools or for writing out to YAML or JSON.
The CLI should support most of the options available on the API.
However:
Create a new certificate using a certificate signing request.
As a user
I want create a certificate
So that so that I can use it with a provisioning profile.
Covering this API.
asc certificates create ios_development --csrFile CertificateRequest.csr
GIVEN I provide a valid certificate type and CSR
WHEN I issue a create command
THEN a certificate is created.
GIVEN I provide a invalid certificate type or CSR
WHEN I issue a create command
THEN I receive an appropriate error message.
GIVEN I provide valid inputs to the create command
WHEN the API fails
THEN I receive an appropriate error message.
Create a beta group associated with an app, optionally enabling TestFlight public links.
As a user
I want create beta groups for my app
So that I can start adding beta testers to them
Covering this API.
asc testflight betagroup create appBundleId groupName --[no]-public-link --public-link-limit <n>
Notes:
@Flag
's support for negation with no
prefix.--public-link-limit
implies that publicLinkLimitEnabled
should be true in the BetaGroupCreateRequest.Data.Attributes
.Output:
App Bundle ID | App Name | Group Name | Is Internal | Public Link | Public Link Enabled | Public Link Limit | Public Link Limit Enabled | Creation Date |
---|
GIVEN I provide invalid input
WHEN I issue the command
THEN an appropriate error message should be displayed
GIVEN I provide valid input
WHEN I issue the command
THEN the output should be displayed
Beta Group is an essential part of the whole Test Flight workflow. When inviting a tester, we have to eight invite them to a specific build, or invite them to a group.
As a user
I want to be able to
Covering APIs
BetaTester is in another issue #12
Add one or more beta testers to a specific beta group.
As a user
I want add an existing beta tester to beta groups
So that so I can manage user access
Covering this API.
asc testflight betatesters addgroup emailAddress groups...
asc testflight betagroup adduser emailAddresses...
GIVEN ...
WHEN ...
THEN ...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.