154 lines
10 KiB
Markdown
154 lines
10 KiB
Markdown
<!--
|
|
# SPDX-License-Identifier: BSD-2-Clause
|
|
# SPDX-FileCopyrightText: 2023 KDE e.V.
|
|
# SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
|
|
-->
|
|
|
|
# microsoftstorepublisher.py - A Microsoft Store Publishing Service
|
|
|
|
This services submits apps to Microsoft Store.
|
|
|
|
## Prerequisites
|
|
|
|
The service needs an SFTP server for exchanging data with the clients.
|
|
|
|
## Installation
|
|
|
|
### Install the Service
|
|
|
|
Clone this repository on a server that shall provide the service,
|
|
create a virtual environment, and install the requirements.
|
|
|
|
```sh
|
|
git clone https://invent.kde.org/sysadmin/ci-notary-service.git microsoftstorepublisher
|
|
cd microsoftstorepublisher
|
|
python3 -m venv .venv
|
|
. .venv/bin/activate
|
|
pip3 install -r requirements_microsoftstore.txt
|
|
```
|
|
|
|
### Configure the Service
|
|
|
|
Copy `microsoftstorepublisher.sample.ini` to `microsoftstorepublisher.ini` and replace the example values
|
|
with the appropriate values for your installation.
|
|
|
|
Then copy `microsoftstorepublisher-projects.sample.yaml` to `microsoftstorepublisher-projects.yaml` and
|
|
specify the settings for the projects you want to submit to the Microsoft Store.
|
|
|
|
## Run the Service
|
|
|
|
Activate the virtual environment and start `microsoftstorepublisher.py`.
|
|
|
|
```sh
|
|
cd ~/microsoftstorepublisher
|
|
. .venv/bin/activate
|
|
python3 microsoftstorepublisher.py --id workerA --config microsoftstorepublisher.ini
|
|
```
|
|
|
|
where you replace `workerA` with a unique alpha-numeric ID for each instance
|
|
of `microsoftstorepublisher.py` you start.
|
|
|
|
## Use the Service to Submit an APPX Package
|
|
|
|
Clone this repository on the client, create a virtual environment, and install
|
|
the requirements.
|
|
|
|
```sh
|
|
git clone https://invent.kde.org/sysadmin/ci-notary-service.git microsoftstorepublisher
|
|
cd microsoftstorepublisher
|
|
python3 -m venv .venv
|
|
. .venv/bin/activate
|
|
pip3 install -r requirements.txt
|
|
```
|
|
|
|
Copy `publishonmicrosoftstore.sample.ini` to `publishonmicrosoftstore.ini` and replace the example values
|
|
with the appropriate values for your installation. In particular, the value
|
|
for `BasePath` must match the corresponding value in the settings of the
|
|
service.
|
|
|
|
Then run `publishonmicrosoftstore.py` to submit an .appxupload file.
|
|
|
|
```sh
|
|
python3 publishonmicrosoftstore.py --config publishonmicrosoftstore.ini <appxupload>
|
|
```
|
|
|
|
where `<appxupload>` is the .appxupload file you want to submit.
|
|
|
|
Note that the service does not commit the submission. This allows you to have a
|
|
final look at the submission in the [Microsoft Partner Center](https://partner.microsoft.com/en-us/dashboard/windows/overview)
|
|
before you commit it from there.
|
|
|
|
Also note that the very first submission has to be made via the Microsoft Partner
|
|
Center to fill out the age restriction questionnaire. There are also other values
|
|
that cannot be changed with the submission API.
|
|
|
|
## Manage the Service with systemd
|
|
|
|
We set up the service under the user's control with a per-user systemd instance.
|
|
|
|
Copy `microsoftstorepublisher-user.sample.service` to `~/.config/systemd/user/microsoftstorepublisher-user.service`
|
|
and modify it as needed. The example uses the username as ID of the service
|
|
worker. Make sure that the ID is unique if you run multiple service workers.
|
|
|
|
Start the service with
|
|
|
|
```sh
|
|
systemctl --user start microsoftstorepublisher-user.service
|
|
```
|
|
|
|
If you want the service to be started automatically, then enable autostart with
|
|
|
|
```sh
|
|
systemctl --user enable microsoftstorepublisher-user.service
|
|
```
|
|
|
|
Note: By default, the systemd user instance and thus the user-managed services are
|
|
started after the first login of a user and killed after the last session of the
|
|
user is closed. To start the user instance right after boot, and keep the systemd
|
|
user instance running after the last session closes you have to enable lingering
|
|
for the user:
|
|
|
|
```sh
|
|
loginctl enable-linger USERNAME
|
|
```
|
|
|
|
For more details on user-managed services see https://wiki.archlinux.org/title/Systemd/User.
|
|
|
|
## How the Service Updates the App's Information in the Store
|
|
|
|
Additionally to uploading the `.appxupload` file to the Microsoft Store, the service
|
|
updates the information of the last published submission with the information found
|
|
in the AppStream data of the app (including translations). The Store ID is extracted
|
|
from the Microsoft Store URL of the app which is stored in the AppStream data as
|
|
custom value with key `KDE::windows_store`.
|
|
The script will add a store listing for each language with a non-empty Description
|
|
in the AppStream data. By default, existing listing values are overwritten with
|
|
corresponding AppStream values for a language. To keep existing non-empty values
|
|
set the `keep` option for your project in the project settings file (`microsoftstorepublisher-projects.yaml`)
|
|
to a comma-separated list of the values to keep.
|
|
|
|
| Listing Value | AppStream Value | Notes |
|
|
| ------------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| copyrightAndTrademarkInfo | - | |
|
|
| description | `description` | Uses value for language. |
|
|
| keywords | `keywords` | Uses values for language. |
|
|
| licenseTerms | `project_license` | |
|
|
| features | - | |
|
|
| releaseNotes | `releases` | Uses `description` of first `release` for language (with fallback to English). |
|
|
| images | `screenshots` | Uses the Windows-specific `screenshot` (i.e. those with `environment="windows"`) or, as fallback, all `screenshot` with `type="default"` marking files with "mobile" in the name as MobileScreenshot; uses `caption` for language as image description. |
|
|
| recommendedHardware | - | |
|
|
| minimumHardware | - | |
|
|
| title | - | must be a reserved name; we keep what's there or use the primaryName of the [Application resource](https://learn.microsoft.com/en-us/windows/uwp/monetize/get-app-data#application-resource) |
|
|
| shortDescription | `summary` | Uses value for language. |
|
|
| shortTitle | - | |
|
|
| sortTitle | - | |
|
|
| voiceTitle | - | |
|
|
| devStudio | `developer_name` | Uses value for language (with fallback to English). |
|
|
|
|
See [Base listing resource](https://learn.microsoft.com/en-us/windows/uwp/monetize/manage-app-submissions#base-listing-object)
|
|
for a description of the listing values. Listing values which have no equivalent
|
|
in the AppStream data can be filled out manually in the
|
|
[Microsoft Partner Center](https://partner.microsoft.com/en-us/dashboard/windows/overview).
|
|
If you want to make sure that those values are not overwritten once AppStream
|
|
provides this information and the script has been updated, then add those
|
|
values to the list of values to keep.
|