From 554fbedeb82737c3d98dc23b06355a2d51d92dd4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 2 May 2026 11:14:03 +0000 Subject: [PATCH 1/4] feat: add netlify-preview job for pull request previews Agent-Logs-Url: https://github.com/nextcloud/documentation/sessions/2ddfd14a-e41d-41f7-a32b-ae5aa616ab41 Co-authored-by: skjnldsv <14975046+skjnldsv@users.noreply.github.com> --- .github/workflows/sphinxbuild.yml | 197 +++++++++++++++++++++++++++++- 1 file changed, 192 insertions(+), 5 deletions(-) diff --git a/.github/workflows/sphinxbuild.yml b/.github/workflows/sphinxbuild.yml index c073621feac..9d94914091d 100644 --- a/.github/workflows/sphinxbuild.yml +++ b/.github/workflows/sphinxbuild.yml @@ -554,8 +554,195 @@ jobs: env: GH_TOKEN: ${{ secrets.COMMAND_BOT_PAT }} + # ============================================================================ + # NETLIFY PREVIEW + # ============================================================================ + # Runs only on pull requests, in parallel with link-check. + # Downloads the staged-docs artifact (already produced by stage-and-check) + # and deploys a preview to Netlify under a stable per-PR alias. + # + # Required repository secrets: + # NETLIFY_AUTH_TOKEN – personal-access token for the Netlify account + # NETLIFY_SITE_ID – the target Netlify site ID + # + # Failure is non-fatal: the step uses continue-on-error so a missing secret + # or a Netlify outage does not block the pull request. + # ============================================================================ + netlify-preview: + name: Deploy Netlify preview + needs: stage-and-check + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + + permissions: + contents: read + pull-requests: write + + steps: + - name: Download staged artifacts + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: staged-docs + path: stage/ + + - name: Assemble Netlify deploy directory + run: | + branch="${{ needs.stage-and-check.outputs.branch_name }}" + mkdir -p netlify-deploy + + # Copy each manual directory into the deploy directory + for manual in admin_manual developer_manual user_manual; do + if [ -d "stage/${branch}/${manual}" ]; then + cp -r "stage/${branch}/${manual}" "netlify-deploy/${manual}" + fi + done + + # PDF files (kept at root of deploy dir) + find "stage/${branch}" -maxdepth 1 -name "*.pdf" -exec cp {} netlify-deploy/ \; + + # Minimal root index linking to the deployed content + cat > netlify-deploy/index.html <<'EOF' + + + + + + Nextcloud Documentation Preview + + + +

Nextcloud Documentation Preview

+ + + + EOF + + - name: List deploy directory tree + run: find netlify-deploy -print | sort + + - name: Install Netlify CLI + run: npm install -g netlify-cli + + - name: Deploy to Netlify + id: netlify + continue-on-error: true + run: | + set +e + output=$(netlify deploy \ + --dir=netlify-deploy \ + --site="${{ secrets.NETLIFY_SITE_ID }}" \ + --auth="${{ secrets.NETLIFY_AUTH_TOKEN }}" \ + --alias="pr-${{ github.event.pull_request.number }}" \ + --message="Preview for PR #${{ github.event.pull_request.number }}" 2>&1) + exit_code=$? + echo "$output" + # Strip ANSI codes, then extract the URL from "Draft URL: " + preview_url=$(printf '%s\n' "$output" \ + | sed 's/\x1b\[[0-9;]*[mGKHFJABCDsuKl]//g' \ + | grep -oP '(?:Draft URL|Website Draft URL|Website URL):\s+\s]+' \ + | head -1) + echo "url=${preview_url}" >> "$GITHUB_OUTPUT" + exit $exit_code + + - name: Post PR preview comment + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + PREVIEW_URL: ${{ steps.netlify.outputs.url }} + with: + script: | + const previewUrl = process.env.PREVIEW_URL || ''; + const prNumber = context.payload.pull_request.number; + const MAX_LINKS = 20; + const COMMENT_MARKER = ''; + const updatedAt = new Date().toUTCString(); + + // Fetch all changed files in the PR (auto-paginated) + const allFiles = await github.paginate(github.rest.pulls.listFiles, { + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: prNumber, + per_page: 100, + }); + + // Keep only RST files that live inside a built manual + const manuals = ['admin_manual/', 'developer_manual/', 'user_manual/']; + const rstFiles = allFiles + .map(f => f.filename) + .filter(f => manuals.some(m => f.startsWith(m)) && f.endsWith('.rst')); + + // Build the changed-pages section + let changedSection = ''; + if (previewUrl && rstFiles.length > 0) { + const links = rstFiles.map(f => { + // user_manual HTML is deployed under user_manual/en/; other manuals deploy as-is + const htmlPath = f.startsWith('user_manual/') + ? f.replace(/^user_manual\//, 'user_manual/en/').replace(/\.rst$/, '.html') + : f.replace(/\.rst$/, '.html'); + return `- [${f}](${previewUrl}/${htmlPath})`; + }); + const shown = links.slice(0, MAX_LINKS); + const extra = links.length - shown.length; + const extraLine = extra > 0 + ? `\n_…and ${extra} more. [View all changed files](https://github.com/${context.repo.owner}/${context.repo.repo}/pull/${prNumber}/files)_` + : ''; + changedSection = [ + '', + `
`, + `📄 ${rstFiles.length} changed documentation ${rstFiles.length === 1 ? 'page' : 'pages'}`, + '', + shown.join('\n') + extraLine, + '
', + ].join('\n'); + } else if (rstFiles.length === 0) { + changedSection = '\n_No RST documentation pages changed in this PR._'; + } + + // Compose the full comment body + const previewLine = previewUrl + ? `🔍 **[Open preview →](${previewUrl})**` + : '⚠️ Preview deployment failed or was skipped.'; + const body = [ + COMMENT_MARKER, + '## 📖 Documentation Preview', + '', + previewLine, + changedSection, + '', + `_Last updated: ${updatedAt}_`, + ].join('\n'); + + // Update existing bot comment or create a new one + const comments = await github.paginate(github.rest.issues.listComments, { + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + per_page: 100, + }); + const existing = comments.find(c => c.body && c.body.includes(COMMENT_MARKER)); + if (existing) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + body, + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body, + }); + } + summary: - needs: [stage-and-check, link-check, deploy] + needs: [stage-and-check, link-check, deploy, netlify-preview] runs-on: ubuntu-latest-low if: always() @@ -569,9 +756,9 @@ jobs: run: | if ${{ github.event_name == 'pull_request' }} then - echo "This workflow ran for a pull request. We need stage-and-check and link-check to succeed, but deploy will be skipped" - if ${{ needs.stage-and-check.result != 'success' || needs.link-check.result != 'success' || needs.deploy.result != 'skipped' }}; then exit 1; fi + echo "This workflow ran for a pull request. We need stage-and-check, link-check, and netlify-preview to succeed, and deploy must be skipped" + if ${{ needs.stage-and-check.result != 'success' || needs.link-check.result != 'success' || needs.deploy.result != 'skipped' || needs.netlify-preview.result != 'success' }}; then exit 1; fi else - echo "This workflow ran for a push. We need all jobs to succeed, including deploy" - if ${{ needs.stage-and-check.result != 'success' || needs.link-check.result != 'success' || needs.deploy.result != 'success' }}; then exit 1; fi + echo "This workflow ran for a push. We need stage-and-check, link-check, and deploy to succeed; netlify-preview must be skipped" + if ${{ needs.stage-and-check.result != 'success' || needs.link-check.result != 'success' || needs.deploy.result != 'success' || needs.netlify-preview.result != 'skipped' }}; then exit 1; fi fi From 40f57e9ddf0cfe0b2cab5262037591030378f2d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Sun, 3 May 2026 18:00:58 +0200 Subject: [PATCH 2/4] fix: add netlify badge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- README.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.rst b/README.rst index 224bc62218d..f0eaec39b96 100644 --- a/README.rst +++ b/README.rst @@ -2,6 +2,15 @@ Nextcloud Documentation ======================= +|build| |netlify| + +.. |build| image:: https://img.shields.io/github/actions/workflow/status/nextcloud/documentation/sphinxbuild.yml?branch=master&style=flat-square + :alt: Build Status + +.. |netlify| image:: https://img.shields.io/badge/Netlify-powered-00C7B7?style=flat-square&logo=netlify + :target: https://www.netlify.com + :alt: Netlify + Documentation is published on ``_. To edit it yourself, you need to tinker a bit with Git and Sphinx. See the `Style Guide `_ for formatting and style conventions. From 558153586cfe59ac1d77495a7626645789044f25 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 3 May 2026 11:56:17 +0000 Subject: [PATCH 3/4] docs: small wording and link consistency fixes across 5 files Agent-Logs-Url: https://github.com/nextcloud/documentation/sessions/64a22427-69ec-446d-aab0-d40a9260eea0 Co-authored-by: skjnldsv <14975046+skjnldsv@users.noreply.github.com> --- admin_manual/index.rst | 8 ++++++-- user_manual/session_management.rst | 6 +++--- user_manual/user_2fa.rst | 5 +++-- user_manual/userpreferences.rst | 6 +++--- user_manual/webinterface.rst | 6 +++--- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/admin_manual/index.rst b/admin_manual/index.rst index 8cb2e40c416..6b1169ddb1a 100644 --- a/admin_manual/index.rst +++ b/admin_manual/index.rst @@ -4,9 +4,13 @@ Introduction **Welcome to the Nextcloud Server Administration Guide.** -This guide explains how to perform administrative tasks in Nextcloud, a highly versatile and scalable open-source platform for file synchronization and content collaboration. +This guide explains how to perform administrative tasks in Nextcloud, a highly versatile and scalable +open-source platform for file synchronization and content collaboration. -With over 400,000 deployments, Nextcloud can run on a simple two-user Raspberry Pi or scale to support global, distributed installations serving tens of millions of users. It can be deployed on-premises, in private or public clouds, or in hybrid environments. Supported by a large and growing community, Nextcloud is available in more than 60 languages. +With over 400,000 deployments, Nextcloud can run on a simple two-user Raspberry Pi or scale to support +global, distributed installations serving tens of millions of users. It can be deployed on-premises, +in private or public clouds, or in hybrid environments. Supported by a large and growing community, +Nextcloud is available in more than 60 languages. The latest editions of the Nextcloud manuals are always available online at `docs.nextcloud.com `_. diff --git a/user_manual/session_management.rst b/user_manual/session_management.rst index 2c9c4212f10..cab5fdbc955 100644 --- a/user_manual/session_management.rst +++ b/user_manual/session_management.rst @@ -38,14 +38,14 @@ those individually if necessary: .. figure:: images/settings_devices_add.png :alt: Adding a new device. -.. note:: You have only access to the device password when creating it, - Nextcloud will not save the plain password, hence it's recommended to +.. note:: You only have access to the device password when creating it. + Nextcloud will not save the plain password, so it is recommended to enter the password on the new client immediately. .. note:: If you use :doc:`user_2fa` for your account, device-specific passwords are the only way to configure clients. The - server will deny connections of clients using your login password then. + server will then deny connections from clients using your login password. Device-specific passwords and password changes ---------------------------------------------- diff --git a/user_manual/user_2fa.rst b/user_manual/user_2fa.rst index 92bc822ef28..c202c026674 100644 --- a/user_manual/user_2fa.rst +++ b/user_manual/user_2fa.rst @@ -75,6 +75,7 @@ If the code was correct you will be redirected to your Nextcloud account. Using two-factor authentication with hardware tokens ---------------------------------------------------- + You can use two-factor authentication based on hardware tokens. The following devices are known to work: * TOTP based: @@ -92,12 +93,12 @@ Using client applications with two-factor authentication Once you have enabled 2FA, your clients will no longer be able to connect with just your password unless they also have support for two-factor authentication. -To solve this, you should generate device specific passwords for them. See +To solve this, you should generate device-specific passwords for them. See :doc:`session_management` for more information on how to do this. Considerations -------------- -If you use WebAuthn to login to your Nextcloud be sure to not use the same token for 2FA. As this +If you use WebAuthn to log in to your Nextcloud, be sure to not use the same token for 2FA, as this would mean you are again only using a single factor. diff --git a/user_manual/userpreferences.rst b/user_manual/userpreferences.rst index 77e348abf1f..598e5660f83 100644 --- a/user_manual/userpreferences.rst +++ b/user_manual/userpreferences.rst @@ -41,7 +41,7 @@ include the following: * Social sharing links * Nextcloud version -.. note:: Available options and settings depending on your administrator's configuration. +.. note:: Available options and settings depend on your administrator's configuration. If you are not able to change the password or the display name in your personal settings, please contact your administrator for help. @@ -73,7 +73,7 @@ Someone with a public facing role such as marketing or sales might want to share Restrict who can see your profile data ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If the profile is enabled by your administrator, then your profile data can be read by other users and guest. +If the profile is enabled by your administrator, then your profile data can be read by other users and guests. To control who can see which information you can adjust the scopes already mentioned: * **Private** will only allow you and users you have added to your phone book to see the data @@ -87,7 +87,7 @@ On the personal settings you can find the button for profile visibility: :alt: screenshot of the profile visibility button in personal settings -Which allows to configure the visibility for each profile attribute: +Which allows you to configure the visibility for each profile attribute: .. figure:: images/userdata-visibility.png :alt: screenshot of scope dropdown on personal information form field diff --git a/user_manual/webinterface.rst b/user_manual/webinterface.rst index 12a4ab28326..6c46e39d30c 100644 --- a/user_manual/webinterface.rst +++ b/user_manual/webinterface.rst @@ -19,8 +19,8 @@ you use the latest and supported version of a browser from this list: * Apple **Safari** (Desktop and iOS) * Microsoft **Edge** -.. note:: Not all versions are supported. Nextcloud is tested and built to work with `these versions only. - `_ +.. note:: Not all versions are supported. Nextcloud is tested and built to work with + `these browser versions `_ only. .. note:: If you want to use Nextcloud Talk you need to run Mozilla **Firefox** 52+ or Google **Chrome**/Chromium 49+ to have the full experience with video calls and @@ -57,7 +57,7 @@ The Nextcloud user interface contains the following fields and functions: * **Navigation Bar** (4): Located over the main viewing window (the Application View), this bar provides a type of breadcrumbs navigation that enables you to - migrate to higher levels of the folder hierarchy up to the root level (home). + navigate to higher levels of the folder hierarchy up to the root level (home). * **New** button (5): Located in the Navigation Bar, the ``New`` button enables you to create new files, new folders, or upload files. From 4d5733203e463a612dc5d710e8a1739e7defd245 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 3 May 2026 16:17:38 +0000 Subject: [PATCH 4/4] ci: fix link-check by remapping /server/latest/ to staged branch directory Agent-Logs-Url: https://github.com/nextcloud/documentation/sessions/44287e46-7e27-4d7d-962d-2143aa5b1677 Co-authored-by: skjnldsv <14975046+skjnldsv@users.noreply.github.com> --- .github/workflows/sphinxbuild.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/sphinxbuild.yml b/.github/workflows/sphinxbuild.yml index 9d94914091d..8f74692f149 100644 --- a/.github/workflows/sphinxbuild.yml +++ b/.github/workflows/sphinxbuild.yml @@ -404,6 +404,7 @@ jobs: args: | --root-dir "$(pwd)/stage" --offline --no-progress + --remap "https://docs.nextcloud.com/server/latest/ file://$(pwd)/stage/${{ needs.stage-and-check.outputs.branch_name }}/" --remap "https://docs.nextcloud.com/server/ file://$(pwd)/stage/" --exclude 'go\.php' --exclude 'mailto:' --exclude-path '.*/404\.html' --exclude-path '.*/_static/.*' --exclude "/user_manual/" --include "/user_manual/en/"