Skip to content

Commit

Permalink
Merge master into stable (#4)
Browse files Browse the repository at this point in the history
* Update tags automatically

* Allow username + password for NC appstore authentication (#3)

* Add username pw auth and tests

* Curl fail on non 200

* Fail script on error

* Try fix function not found error

* Source

* Basics for testing

* Add more tests

* Update readme (username + password)
  • Loading branch information
R0Wi authored Oct 7, 2020
1 parent ecf1b8a commit 294fe91
Show file tree
Hide file tree
Showing 14 changed files with 691 additions and 20 deletions.
18 changes: 18 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Run tests

on:
pull_request:
push:

jobs:
runtests:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install test environment
run: sudo apt-get update && sudo apt-get -y install bats nodejs npm
- name: Install node dependencies
run: cd test && npm install
- name: Run tests
run: cd test && chmod +x run_tests.sh && ./run_tests.sh
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
test/node_modules
test/test_app.tar.gz
test/server_output.txt
45 changes: 28 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,31 @@
This Github Action automatically publishes a new app version in the Nextcloud appstore after you created a new Github release.

## Workflow
The following workflow will be automated by this Action:
The following workflow can be automated when using this Github Action:

1. Develop your app.
2. Create a new [release](https://docs.github.com/en/github/administering-a-repository/managing-releases-in-a-repository).
3. Let a new Github Workflow be triggered which automates the following steps:
1. Create a new [release](https://docs.github.com/en/github/administering-a-repository/managing-releases-in-a-repository) of your app in Github.
2. Let a new Github Workflow be triggered which automates the following steps:
- Chechout the `tag` version of your new release.
- Build a tarball for your app.
- Attach the tarball to the Github Release.
- Upload a new app version into the Nextcloud appstore referencing your attached tarball. This includes creating a signature and authenticating against Nextcloud's appstore via token.
- Upload a new app version into the Nextcloud appstore referencing your attached tarball. This includes creating a signature and authenticating against Nextcloud's appstore via token (or username and password).

## Prerequisites
1. **Register** you app in the Nextcloud appstore like described [here](https://nextcloudappstore.readthedocs.io/en/latest/developer.html).
2. Paste the content of your app's **private key into a new [Github Secret](https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets)** of your app's repository (e.g. with the key `APP_PRIVATE_KEY`). This key is later used for signing the new app version before uploading it to the appstore.
3. Create a new [Github Secret](https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets) for your **Nextcloud appstore account [token](https://nextcloudappstore.readthedocs.io/en/latest/restapi.html#authentication)** (e.g. with the key `APPSTORE_TOKEN`). The token can be copied by logging into https://apps.nextcloud.com an then visiting *My account -> API-Token*.
4. Make sure you are able to build a tarball for your app inside of Github actions. This could be achieved by using an appropriate [`Makefile`](https://github.com/nextcloud/files_photospheres/blob/master/Makefile).
2. Paste the content of your app's **private key into a new [Github Secret](https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets)** named `APP_PRIVATE_KEY`. This key is later used for signing the new app version before uploading it to the appstore.

3. For **authentication** against the Nextcloud appstore you can use one of the following approaches:
1. **Token** (recommended): create a new [Github Secret](https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets) for your Nextcloud appstore account [token](https://nextcloudappstore.readthedocs.io/en/latest/restapi.html#authentication) named `APPSTORE_TOKEN`. The token can be copied by logging into https://apps.nextcloud.com an then visiting *My account -> API-Token*.
2. **Username & password**: create two [Github Secrets](https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets) `APPSTORE_USERNAME` and `APPSTORE_PASSWORD` holding your personal login information for the [Nextcloud appstore](https://apps.nextcloud.com). Make sure this user is allowed to create new app releases for you app.
4. Make sure you are able to build a tarball for your app inside of Github actions. This could be achieved by using an appropriate `Makefile`. Here are two examples:
* https://github.com/nextcloud/files_photospheres/blob/master/Makefile (without [code signing](https://docs.nextcloud.com/server/latest/admin_manual/issues/code_signing.html))
* https://github.com/nextcloud/spreed/blob/b5198c2d0d9cdc2c7c0e410867d2ec84336e23a6/Makefile (with [code signing](https://docs.nextcloud.com/server/latest/admin_manual/issues/code_signing.html))

## Usage
### Example
The following example shows how you can use this Github Action after a new Github Release was created:
In general you'll have to create a new `.yml`-file in your app's repository inside of `.github/workflows` (for example `.github/workflows/build_release.yml`) to use this Github Action. The following sections list a few useful examples on how you can combine this Action with others to automate your workflow. All samples can also be found in the [`examples`](examples) directory of this repository.

### Example without [code signing](https://docs.nextcloud.com/server/latest/admin_manual/issues/code_signing.html)
The following example shows how you can use this Github Action with your Nextcloud Appstore token after a new Github Release was created:

```yaml
name: Build and publish app release
Expand Down Expand Up @@ -62,13 +68,18 @@ jobs:

```

> You'll have to store this file inside of your app's repository. For example under `.github/workflows/build_release.yml`.
### Input variables
* `app_name`: The id of your Nextcloud app *(required)*
* `appstore_token`: A valid access token to upload a new version of your app into Nextcloud appstore *(required)*
* `download_url`: The download url of you app tarball *(required)*
* `app_private_key`: The private key string of you app to sign the new release. Usually stored in Github Secrets *(required)*
* `nightly`: Controls if the app will be published as nightly into the Nextcloud appstore *(optional, default = `false`)*
| Name | Description | Default | Possible values | Required |
|-------------------|---------------------------------------------------------------------------------------------|---------|-----------------|----------|
| `app_name` | The id of your Nextcloud app | - | `string` | `true` |
| `appstore_token` | A valid access token to upload a new version of your app into Nextcloud appstore | - | `string` | `false`* |
| `appstore_username` | Username for Nextcloud appstore | - | `string` | `false`* |
| `appstore_password` | Password for Nextcloud appstore | - | `string` | `false`* |
| `download_url` | The download url of you app tarball | - | `string` | `true` |
| `app_private_key` | The private key string of you app to sign the new release. Usually stored in Github Secrets | - | `string` | `true` |
| `nightly` | Controls if the app will be published as nightly into the Nextcloud appstore | `false` | `true`, `false` | `false` |

> *Either `appstore_token` or `appstore_username` **and** `appstore_password` must be set.
### Output variables
There are currently no output variables.
10 changes: 9 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ inputs:
required: true
appstore_token:
description: 'A valid access token to upload a new version of your app into Nextcloud appstore'
required: true
required: false
appstore_username:
description: 'Username for Nextcloud appstore'
required: false
appstore_password:
description: 'Password for Nextcloud appstore'
required: false
download_url:
description: 'The download url of you app tarball'
required: true
Expand All @@ -27,6 +33,8 @@ runs:
env:
APP_NAME: ${{ inputs.app_name }}
APPSTORE_TOKEN: ${{ inputs.appstore_token }}
APPSTORE_USERNAME: ${{ inputs.appstore_username }}
APPSTORE_PASSWORD: ${{ inputs.appstore_password }}
NIGHTLY: ${{ inputs.nightly }}
DOWNLOAD_URL: ${{ inputs.download_url }}
APP_PRIVATE_KEY_FILE: ${{ github.workspace }}/${{ inputs.app_name }}.key
Expand Down
File renamed without changes.
7 changes: 7 additions & 0 deletions functions.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

# $1 = private key file
# $2 = app tar file
function createsign {
echo "`openssl dgst -sha512 -sign $1 $2 | openssl base64 -A`"
}
24 changes: 22 additions & 2 deletions push_appstore.sh
Original file line number Diff line number Diff line change
@@ -1,17 +1,37 @@
#!/bin/bash
set -eo pipefail

# Used environment-variables:
# APP_NAME
# APPSTORE_TOKEN
# APPSTORE_USERNAME
# APPSTORE_PASSWORD
# NIGHTLY
# DOWNLOAD_URL
# APP_PRIVATE_KEY_FILE

script_dir="$(dirname "$0")"
appstore_url=$APPSTORE_URL || "https://apps.nextcloud.com/api/v1/apps/releases"

. "${script_dir}/functions.sh"

echo "Downloading app tarball for signing"
wget "$DOWNLOAD_URL" -O "${APP_NAME}.tar.gz"

echo "Creating signature for app release"
sign="`openssl dgst -sha512 -sign ${APP_PRIVATE_KEY_FILE} ${APP_NAME}.tar.gz | openssl base64 -A`"
sign="`createsign ${APP_PRIVATE_KEY_FILE} ${APP_NAME}.tar.gz`"

echo "Creating new app release in Nextcloud appstore (nightly=${NIGHTLY})"
curl -X POST https://apps.nextcloud.com/api/v1/apps/releases -H "Authorization: Token ${APPSTORE_TOKEN}" -H "Content-Type: application/json" -d "{\"download\":\"${DOWNLOAD_URL}\", \"signature\": \"${sign}\", \"nightly\": ${NIGHTLY} }"

if [ ! -z $APPSTORE_TOKEN ]
then
echo "Using token authentication"
curl -s --fail --show-error -X POST $appstore_url -H "Authorization: Token ${APPSTORE_TOKEN}" -H "Content-Type: application/json" -d "{\"download\": \"${DOWNLOAD_URL}\", \"signature\": \"${sign}\", \"nightly\": ${NIGHTLY} }"
elif [ ! -z $APPSTORE_USERNAME ] && [ ! -z $APPSTORE_PASSWORD ]
then
echo "Using username password authentication"
curl -s --fail --show-error -X POST $appstore_url -u "${APPSTORE_USERNAME}:${APPSTORE_PASSWORD}" -H "Content-Type: application/json" -d "{\"download\": \"${DOWNLOAD_URL}\", \"signature\": \"${sign}\", \"nightly\": ${NIGHTLY} }"
else
echo "Authentication cannot be done. Please provide 'appstore_token' or 'appstore_username' and 'appstore_password' input variables."
exit 1
fi
Loading

0 comments on commit 294fe91

Please sign in to comment.