Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
204 changes: 204 additions & 0 deletions .github/scripts/build-and-release-app-for-upgrade-testing.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
# SPDX-FileCopyrightText: 2023-2024 Jankari Tech Pvt. Ltd.
# SPDX-FileCopyrightText: 2023 Bundesministerium des Innern und für Heimat, PG ZenDiS "Projektgruppe für Aufbau ZenDiS"
# SPDX-FileCopyrightText: 2023 Nextcloud GmbH
# SPDX-License-Identifier: AGPL-3.0-only
#!/usr/bin/env bash

# This bash script is to register and publish the apps in self-hosted appstore.
# To run this script the self-hosted appstore instances must be up and running

set -e

# helper functions
log_error() {
echo -e "\e[31m$1\e[0m"
}

log_info() {
echo -e "\e[37m$1\e[0m"
}

log_success() {
echo -e "\e[32m$1\e[0m"
}

# env required
# NEXCLOUD_PATH=/home/nabin/www/stable29 # path to nextcloud
# $TAG=2.11.3 # tag that we want to publish
# WORKING_DIRECTORY=/home/nabin/www/fork-integrationOpenproject # current working directory simply done by pwd command

if [[ -z "$TAG" ]] || [[ -z "$NEXCLOUD_PATH" ]] || [[ -z "$WORKING_DIRECTORY" ]]; then
log_error "Environment variables TAG, NEXCLOUD_PATH, or WORKING_DIRECTORY are missing."
exit 1
fi

if [[ ! -d "$WORKING_DIRECTORY/integration_openproject" ]]; then
log_error "integration_openproject directory does not exist."
exit 1
fi

# build the apps
cd $WORKING_DIRECTORY
make -C integration_openproject

mkdir -p publish

# remove unnecessary app files
log_info "Copying necessary app files to publish directory..."
rsync -a \
--exclude=server \
--exclude=dev \
--exclude=.git \
--exclude=appinfo/signature.json \
--exclude='*.swp' \
--exclude=build \
--exclude=.gitignore \
--exclude=.travis.yml \
--exclude=.scrutinizer.yml \
--exclude=CONTRIBUTING.md \
--exclude=composer.phar \
--exclude=js/node_modules \
--exclude=node_modules \
--exclude=src \
--exclude=translationfiles \
--exclude='webpack.*' \
--exclude=stylelint.config.js \
--exclude=.eslintrc.js \
--exclude=.github \
--exclude=.gitlab-ci.yml \
--exclude=crowdin.yml \
--exclude=tools \
--exclude=.tx \
--exclude=.l10nignore \
--exclude=l10n/.tx \
--exclude=l10n/l10n.pl \
--exclude=l10n/templates \
--exclude='l10n/*.sh' \
--exclude='l10n/[a-z][a-z]' \
--exclude='l10n/[a-z][a-z]_[A-Z][A-Z]' \
--exclude=l10n/no-php \
--exclude=makefile \
--exclude=screenshots \
--exclude='phpunit*xml' \
--exclude=tests \
--exclude=ci \
--exclude=vendor/bin \
integration_openproject publish/

cd publish

# update version in info.xml
sed -i "s|<version>.*</version>|<version>$TAG</version>|" "integration_openproject/appinfo/info.xml"

# https://nextcloudappstore.readthedocs.io/en/latest/developer.html#obtaining-a-certificate
log_info "Generating app.key and app.crt..."
sudo openssl req -x509 -newkey rsa:4096 -sha256 -nodes \
-keyout app.key \
-out app.crt \
-days 3650 \
-subj "/CN=$APP_ID" \
-addext "basicConstraints=CA:FALSE" \
-addext "keyUsage=digitalSignature" \
-addext "extendedKeyUsage=codeSigning"

if [[ ! -s app.key || ! -s app.crt ]]; then
log_error "Failed to generate app signing certificate and key. app.key or app.crt not found."
exit 1
fi

log_info "Adding the generated certificate to nextcloud's root.crt..."
nextcloud_root_crt="${NEXCLOUD_PATH}/resources/codesigning/root.crt"
if [[ -f ${nextcloud_root_crt} ]]; then
echo "" >> ${nextcloud_root_crt}
cat app.crt >> ${nextcloud_root_crt}
else
log_error "Nextcloud's root.crt not found at ${nextcloud_root_crt}."
exit 1
fi

# fix permisions for signing
sudo chown $USER: app.key
sudo chown -R $USER: $APP_ID

# Sign the app
# need full path for signing
log_info "Signing the app using occ integrity:sign-app command..."
php ${NEXCLOUD_PATH}/occ integrity:sign-app \
--privateKey=${WORKING_DIRECTORY}/publish/app.key \
--certificate=${WORKING_DIRECTORY}/publish/app.crt \
--path=${WORKING_DIRECTORY}/publish/$APP_ID || { log_error "Failed to sign app."; exit 1; }

# php /home/runner/html/nextcloud/occ integrity:sign-app \
# --privateKey=/home/runner/work/integration_openproject/integration_openproject/publish/app.key \
# --certificate=/home/runner/work/integration_openproject/integration_openproject/publish/app.crt \
# --path=/home/runner/work/integration_openproject/integration_openproject/publish/integration_openproject

# Archive the app
tar -czf $APP_ID-$TAG.tar.gz $APP_ID
if [[ ! -f $APP_ID-$TAG.tar.gz ]]; then
log_error "Failed to archive the app. Archive file $APP_ID-$TAG.tar.gz not found."
exit 1
fi
log_success "Archived the app into $APP_ID-$TAG.tar.gz."

# Sign the archive
sudo openssl dgst -sha512 -sign app.key $APP_ID-$TAG.tar.gz | openssl base64 | tee ${WORKING_DIRECTORY}/publish/sign.txt || { log_error "Failed to sign the archive."; exit 1; }
if [[ ! -s ${WORKING_DIRECTORY}/publish/sign.txt ]]; then
log_error "Failed to sign the archive. Signature file sign.txt is empty or not found."
exit 1
else
log_success "Signed the app archive successfully."
fi

log_success "App build and release process has been completed successfully."

## copy archieve in nextcloud directory to download
cp $APP_ID-$TAG.tar.gz ${NEXCLOUD_PATH}/$APP_ID-$TAG.tar.gz
if [[ -f ${NEXCLOUD_PATH}/$APP_ID-$TAG.tar.gz ]]; then
log_success "App archive has been copied successfully."
else
log_error "Failed to copy app archive to ${NEXCLOUD_PATH}."
exit 1
fi

## Prepare apps.json file
if [[ ! -f ${WORKING_DIRECTORY}/publish/integration_openproject/appinfo/signature.json ]]; then
log_error "Signature file not found at ${WORKING_DIRECTORY}/publish/integration_openproject/appinfo/signature.json."
exit 1
fi

# Convert sign.txt content to one line by removing newlines
signature=$(tr -d '\n' < "${WORKING_DIRECTORY}/publish/sign.txt")
certificate=$(jq '.certificate' ${WORKING_DIRECTORY}/publish/integration_openproject/appinfo/signature.json)

cat > apps.json <<EOF
[
{
"id": "$APP_ID",
"releases": [
{
"version": "$TAG",
"minIntSize": 32,
"download": "http://localhost/$APP_ID-$TAG.tar.gz",
"licenses": [
"agpl"
],
"isNightly": false,
"rawPlatformVersionSpec": "\u003E=28 \u003C=31",
"signature": "$signature",
"signatureDigest": "sha512"
}
],
"certificate": $certificate
}
]
EOF

cp apps.json ${NEXCLOUD_PATH}

if [[ -f ${NEXCLOUD_PATH}/apps.json ]]; then
log_success "apps.json file has been copied successfully."
else
log_error "Failed to copy apps.json to ${NEXCLOUD_PATH}."
exit 1
fi
26 changes: 13 additions & 13 deletions .github/workflows/ci-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
name: CI

on:
push:
branches:
- 'master'
pull_request:
paths-ignore:
- '**.md'
- '**.txt'
- '**.sh'
- 'dev/**'
- 'l10n/**'
- 'img/**'
- 'docker-compose*'
# on:
# push:
# branches:
# - 'master'
# pull_request:
# paths-ignore:
# - '**.md'
# - '**.txt'
# - '**.sh'
# - 'dev/**'
# - 'l10n/**'
# - 'img/**'
# - 'docker-compose*'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/reuse.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

name: REUSE Compliance Check

on: [pull_request]
# on: [pull_request]

permissions:
contents: read
Expand Down
144 changes: 144 additions & 0 deletions .github/workflows/upgrade-testing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# SPDX-FileCopyrightText: 2026 Jankari Tech Pvt. Ltd.
# SPDX-License-Identifier: AGPL-3.0-or-later

name: Upgrade Testing

on: [pull_request]

env:
TAG: 2.11.3

jobs:
create-matrix:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8

- name: Create matrix
id: create-matrix
env:
NEXTCLOUD_VERSIONS: "31 32"
PHP_VERSIONS: "8.2 8.3"
run: |
MATRIX=$(./.github/scripts/generate-matrix.sh)
echo "matrix={\"include\": [$MATRIX]}" >> $GITHUB_OUTPUT
outputs:
matrix: ${{ steps.create-matrix.outputs.matrix }}

upgrade-test:
name: Upgrade Testing
needs: create-matrix
if: ${{ success() }}
strategy:
matrix: ${{ fromJson(needs.create-matrix.outputs.matrix) }}
runs-on: ubuntu-latest
services:
database-mysql:
image: ghcr.io/nextcloud/continuous-integration-mariadb-10.5:latest
env:
MYSQL_ROOT_PASSWORD: 'nextcloud'
MYSQL_PASSWORD: 'nextcloud'
MYSQL_USER: 'nextcloud'
MYSQL_DATABASE: 'nextcloud'
ports:
- 3306:3306

steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
with:
path: integration_openproject

- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
with:
repository: nextcloud/activity
ref: ${{ matrix.nextcloudVersion }}
path: activity

- name: Setup NodeJS
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
with:
node-version: 20

- name: Setup npm
run: npm i -g npm

- name: Setup PHP
uses: shivammathur/setup-php@a4e22b60bbb9c1021113f2860347b0759f66fe5d
with:
php-version: ${{ format('{0}.{1}', matrix.phpVersionMajor,matrix.phpVersionMinor) }}
extensions: mbstring, intl, mysql, gd
ini-values: post_max_size=256M, max_execution_time=180

- name: Build nextcloud project
run: |
export DEBIAN_FRONTEND=noninteractive
Comment on lines +75 to +77
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

can we start nextcloud in the service section?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Possibly, but why do you think so?

echo "###### installing nextcloud"
mkdir ~/html
git clone https://github.com/nextcloud/server.git --recursive --depth 1 -b ${{ matrix.nextcloudVersion }} ~/html/nextcloud
cd ~/html/nextcloud
git submodule update --init
mkdir -p data
php occ maintenance:install \
--database mysql \
--database-name nextcloud \
--database-host 127.0.0.1 \
--database-user nextcloud \
--database-pass nextcloud \
--admin-user admin \
--admin-pass admin
php occ maintenance:mode --off
sudo php -S localhost:80 -t ~/html/nextcloud &
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

it would be better to run NC with a real web-server like apache, but for now this should be fine


- name: Wait for Nextcloud server to be ready
run: |
if ! timeout 5m bash -c '
until curl -s -f http://localhost/status.php | grep '"'"'"installed":true'"'"'; do
echo "[INFO] Waiting for server to be ready..."
sleep 10
done
'; then
echo "[ERROR] Server not ready within 5 minutes."
exit 1
fi

- name: Enable other apps from official app store
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

this is not entirely true, because at least activity is cloned further up by git

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The Activity app is not available in the App Store. It is a core app of Nextcloud. It is not included when the Nextcloud source is from Git.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

then maybe call the step enable other required apps

run: |
cp -R activity ~/html/nextcloud/apps
cd ~/html/nextcloud
php occ app:enable oidc user_oidc groupfolders activity integration_openproject

- name: Build integration_openproject app for upgrade testing
env:
APP_ID: integration_openproject
NEXCLOUD_PATH: /home/runner/html/nextcloud
WORKING_DIRECTORY: ${{ github.workspace }}
run: |
cd integration_openproject
bash .github/scripts/build-and-release-app-for-upgrade-testing.sh

- name: Update integration_openproject app
run: |
# latest data didn't get fetched properly, so we need to clear the appstore cache
echo "" > ~/html/nextcloud/data/appdata_*/appstore/apps.json
cd ~/html/nextcloud
php occ config:system:set ratelimit.protection.enabled --value false --type bool
php occ config:system:set appstoreurl --value "http://localhost"
php occ config:system:set allow_local_remote_servers --value true
php occ app:update --allow-unstable integration_openproject
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

we should check whether the upgrade to the new version really happened

if php occ app:list | grep -q "integration_openproject.*$TAG"; then
echo "App updated successfully to version $TAG"
else
echo "App not updated to version $TAG"
exit 1
fi

- name: API Tests
env:
NEXTCLOUD_BASE_URL: http://localhost
run: |
cd integration_openproject
# Run API tests
make api-test
Loading
Loading