diff --git a/.github/workflows/appstore-build-publish.yml b/.github/workflows/appstore-build-publish.yml new file mode 100644 index 0000000..2f5c2c2 --- /dev/null +++ b/.github/workflows/appstore-build-publish.yml @@ -0,0 +1,200 @@ +# This workflow is provided via the organization template repository +# +# https://github.com/nextcloud/.github +# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization +# +# SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors +# SPDX-License-Identifier: MIT + +name: Build and publish app release + +on: + release: + types: [published] + +permissions: + contents: write + +jobs: + build_and_publish: + runs-on: ubuntu-latest + + # Only allowed to be run on nextcloud-releases repositories + if: ${{ github.repository_owner == 'nextcloud-releases' }} + + steps: + - name: Check actor permission + uses: skjnldsv/check-actor-permission@69e92a3c4711150929bca9fcf34448c5bf5526e7 # v3.0 + with: + require: write + + - name: Set app env + run: | + # Split and keep last + echo "APP_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV + echo "APP_VERSION=${GITHUB_REF##*/}" >> $GITHUB_ENV + + - name: Checkout + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + path: ${{ env.APP_NAME }} + + - name: Get app version number + id: app-version + uses: skjnldsv/xpath-action@f5b036e9d973f42c86324833fd00be90665fbf77 # v1.0.0 + with: + filename: ${{ env.APP_NAME }}/appinfo/info.xml + expression: "//info//version/text()" + + - name: Validate app version against tag + run: | + [ "${{ env.APP_VERSION }}" = "v${{ fromJSON(steps.app-version.outputs.result).version }}" ] + + - name: Get appinfo data + id: appinfo + uses: skjnldsv/xpath-action@f5b036e9d973f42c86324833fd00be90665fbf77 # v1.0.0 + with: + filename: ${{ env.APP_NAME }}/appinfo/info.xml + expression: "//info//dependencies//nextcloud/@min-version" + + - name: Read package.json node and npm engines version + uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3 + id: versions + # Continue if no package.json + continue-on-error: true + with: + path: ${{ env.APP_NAME }} + fallbackNode: '^24' + fallbackNpm: '^11.3' + + - name: Set up node ${{ steps.versions.outputs.nodeVersion }} + # Skip if no package.json + if: ${{ steps.versions.outputs.nodeVersion }} + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: ${{ steps.versions.outputs.nodeVersion }} + package-manager-cache: false + + - name: Set up npm ${{ steps.versions.outputs.npmVersion }} + # Skip if no package.json + if: ${{ steps.versions.outputs.npmVersion }} + run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}' + + - name: Get php version + id: php-versions + uses: icewind1991/nextcloud-version-matrix@8a7bac6300b2f0f3100088b297995a229558ddba # v1.3.2 + with: + filename: ${{ env.APP_NAME }}/appinfo/info.xml + + - name: Set up php ${{ steps.php-versions.outputs.php-min }} + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2 + with: + php-version: ${{ steps.php-versions.outputs.php-min }} + coverage: none + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Check composer.json + id: check_composer + uses: andstor/file-existence-action@558493d6c74bf472d87c84eab196434afc2fa029 # v3.1.0 + with: + files: "${{ env.APP_NAME }}/composer.json" + + - name: Install composer dependencies + if: steps.check_composer.outputs.files_exists == 'true' + run: | + cd ${{ env.APP_NAME }} + composer install --no-dev + + - name: Build ${{ env.APP_NAME }} + # Skip if no package.json + if: ${{ steps.versions.outputs.nodeVersion }} + env: + CYPRESS_INSTALL_BINARY: 0 + run: | + cd ${{ env.APP_NAME }} + npm ci + npm run build --if-present + + - name: Check Krankerl config + id: krankerl + uses: andstor/file-existence-action@558493d6c74bf472d87c84eab196434afc2fa029 # v3.1.0 + with: + files: ${{ env.APP_NAME }}/krankerl.toml + + - name: Install Krankerl + if: steps.krankerl.outputs.files_exists == 'true' + run: | + wget https://github.com/ChristophWurst/krankerl/releases/download/v0.14.0/krankerl_0.14.0_amd64.deb + sudo dpkg -i krankerl_0.14.0_amd64.deb + + - name: Package ${{ env.APP_NAME }} ${{ env.APP_VERSION }} with krankerl + if: steps.krankerl.outputs.files_exists == 'true' + run: | + cd ${{ env.APP_NAME }} + krankerl package + + - name: Package ${{ env.APP_NAME }} ${{ env.APP_VERSION }} with makefile + if: steps.krankerl.outputs.files_exists != 'true' + run: | + cd ${{ env.APP_NAME }} + make appstore + + - name: Check server download link for ${{ fromJSON(steps.appinfo.outputs.result).nextcloud.min-version }} + run: | + NCVERSION='${{ fromJSON(steps.appinfo.outputs.result).nextcloud.min-version }}' + DOWNLOAD_URL=$(curl -s "https://updates.nextcloud.com/updater_server/latest?channel=beta&version=$NCVERSION" | jq -r '.downloads.zip[0]') + echo "DOWNLOAD_URL=$DOWNLOAD_URL" >> $GITHUB_ENV + + - name: Download server ${{ fromJSON(steps.appinfo.outputs.result).nextcloud.min-version }} + continue-on-error: true + id: server-download + if: ${{ env.DOWNLOAD_URL != 'null' }} + run: | + echo "Downloading release tarball from $DOWNLOAD_URL" + wget $DOWNLOAD_URL -O nextcloud.zip + unzip nextcloud.zip + + - name: Checkout server master fallback + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + if: ${{ steps.server-download.outcome != 'success' }} + with: + persist-credentials: false + submodules: true + repository: nextcloud/server + path: nextcloud + + + - name: Sign app + run: | + # Extracting release + cd ${{ env.APP_NAME }}/build/artifacts + tar -xvf ${{ env.APP_NAME }}.tar.gz + cd ../../../ + # Setting up keys + echo '${{ secrets.APP_PRIVATE_KEY }}' > ${{ env.APP_NAME }}.key + wget --quiet "https://github.com/nextcloud/app-certificate-requests/raw/master/${{ env.APP_NAME }}/${{ env.APP_NAME }}.crt" + # Signing + php nextcloud/occ integrity:sign-app --privateKey=../${{ env.APP_NAME }}.key --certificate=../${{ env.APP_NAME }}.crt --path=../${{ env.APP_NAME }}/build/artifacts/${{ env.APP_NAME }} + # Rebuilding archive + cd ${{ env.APP_NAME }}/build/artifacts + tar -zcvf ${{ env.APP_NAME }}.tar.gz ${{ env.APP_NAME }} + + - name: Attach tarball to github release + uses: svenstaro/upload-release-action@29e53e917877a24fad85510ded594ab3c9ca12de # 2.11.5 + id: attach_to_release + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: ${{ env.APP_NAME }}/build/artifacts/${{ env.APP_NAME }}.tar.gz + asset_name: ${{ env.APP_NAME }}-${{ env.APP_VERSION }}.tar.gz + tag: ${{ github.ref }} + overwrite: true + + - name: Upload app to Nextcloud appstore + uses: nextcloud-releases/nextcloud-appstore-push-action@a011fe619bcf6e77ddebc96f9908e1af4071b9c1 # v1.0.3 + with: + app_name: ${{ env.APP_NAME }} + appstore_token: ${{ secrets.APPSTORE_TOKEN }} + download_url: ${{ steps.attach_to_release.outputs.browser_download_url }} + app_private_key: ${{ secrets.APP_PRIVATE_KEY }} diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e5d39a4 --- /dev/null +++ b/Makefile @@ -0,0 +1,73 @@ +# SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors +# SPDX-License-Identifier: AGPL-3.0-or-later + +app_name=integration_davc + +project_dir=$(CURDIR) +build_dir=$(CURDIR)/build/artifacts +appstore_dir=$(build_dir)/$(app_name) +package_name=$(build_dir)/$(app_name).tar.gz + +# Tools (override on the command line if needed, e.g. `make composer-install COMPOSER=composer2`) +COMPOSER=composer +NPM=npm + +.PHONY: all +all: build + +# Install all dependencies and build the production frontend assets. +.PHONY: build +build: composer-install build-js-production + +# PHP runtime dependencies only (no dev tooling ends up in the package). +.PHONY: composer-install +composer-install: + $(COMPOSER) install --no-dev --prefer-dist --optimize-autoloader + +# Compile the frontend bundle into js/. +.PHONY: build-js-production +build-js-production: + $(NPM) ci + $(NPM) run build --if-present + +# Remove all build output. +.PHONY: clean +clean: + rm -rf $(build_dir) + +# Assemble a clean copy of the app and package it for the Nextcloud App Store. +# NOTE: this only packages what is already present in the working tree. Run +# `make build` (or the CI build steps) first so js/ and vendor/ are populated. +.PHONY: appstore +appstore: clean + mkdir -p $(appstore_dir) + rsync -a \ + --exclude='/build' \ + --exclude='/.git' \ + --exclude='/.github' \ + --exclude='/.tx' \ + --exclude='/.ideas' \ + --exclude='/.vscode' \ + --exclude='/node_modules' \ + --exclude='/src' \ + --exclude='/tests' \ + --exclude='/docs' \ + --exclude='/.phpunit.cache' \ + --exclude='*.cache' \ + --exclude='*.log' \ + --exclude='*.log.*' \ + --exclude='/renovate.json' \ + --exclude='/.l10nignore' \ + --exclude='/.gitignore' \ + --exclude='/eslint.config.mjs' \ + --exclude='/stylelint.config.js' \ + --exclude='/rspack.config.js' \ + --exclude='/tsconfig.json' \ + --exclude='/.php-cs-fixer.dist.php' \ + --exclude='/package.json' \ + --exclude='/package-lock.json' \ + --exclude='/composer.json' \ + --exclude='/composer.lock' \ + --exclude='/Makefile' \ + $(project_dir)/ $(appstore_dir)/ + tar -czf $(package_name) -C $(build_dir) $(app_name)