Skip to content

chore(deps-dev): Bump follow-redirects from 1.16.1 to 1.16.2 #118

chore(deps-dev): Bump follow-redirects from 1.16.1 to 1.16.2

chore(deps-dev): Bump follow-redirects from 1.16.1 to 1.16.2 #118

name: Config Docs In Sync
# The two config parameter pages per server version are generated by
# owncloud/config-to-docs from owncloud/core's config/config.sample.php and
# config/config.apps.sample.php. Everything below the "header end" marker in
# those pages is machine output, and a hand edit there is silently destroyed the
# next time anyone regenerates. This job regenerates and fails on any
# difference, so the published pages are provably generator output and an edit
# in the wrong place is caught here instead of years later.
#
# Deliberately NOT path-filtered. A required check that is skipped reports as
# perpetually pending and blocks merges - the same trap documented at length in
# lint-pr-title.yml. The cost of that choice is that drift introduced by a *core*
# commit surfaces on the next docs PR, whoever opens it; the nightly run below
# exists so it is usually found before then.
on:
push:
branches: [main]
pull_request:
schedule:
# Core can drift this repo without touching it, so look once a day.
- cron: '17 4 * * *'
workflow_dispatch:
permissions:
contents: read
env:
CORE_REPO: https://github.com/owncloud/core.git
jobs:
config-docs-in-sync:
runs-on: ubuntu-latest
# owncloud-owned image, so no third-party action is needed to provide PHP.
container: owncloudci/php:7.4
# Inside a container the default shell is sh, not bash.
defaults:
run:
shell: bash
concurrency:
group: config-docs-in-sync-${{ github.ref }}
cancel-in-progress: true
steps:
- name: Checkout docs
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Checkout config-to-docs
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: owncloud/config-to-docs
path: .config-to-docs
persist-credentials: false
# Deliberately unpinned. This check asks "do the committed pages match
# what a maintainer running ctd.sh today would produce", so it has to
# track the current generator. The composer deps below are pinned
# because the lock file is that generator's own declared contract.
- name: Install the converter
working-directory: .config-to-docs
# install, not update: the comment parsing lives in
# phpdocumentor/reflection-docblock, which composer.json accepts as
# ^4.3.0 while the lock pins a known-good version. Floating it can
# change the generated output.
run: composer install --no-interaction --no-progress --no-dev --no-scripts
- name: Regenerate every version from its core branch
run: |
set -eu
# convert.php exits 0 on both of its own failure paths - unreadable
# input, unwritable output - so nothing here may infer success from an
# exit status. Every file is checked before use, and the pages actually
# regenerated are counted and asserted at the end. Without that, a
# renamed sample in core would leave the pages untouched, the diff
# below would find nothing, and this job would pass having checked
# nothing at all.
versions=0
generated=0
# --branch takes a tag as well as a branch.
fetch_core() {
rm -rf ".core-$version"
# blob:none matters: a plain --depth 1 --sparse clone still transfers
# the whole tree's blobs (~30 MB), this is ~1.5 MB.
git -c advice.detachedHead=false clone --quiet --depth 1 --branch "$1" --filter=blob:none --sparse \
"$CORE_REPO" ".core-$version"
# --no-cone with explicit paths, because cone mode cannot select a
# single root file and version.php is needed for the check below.
git -C ".core-$version" sparse-checkout set --no-cone /config/ /version.php
}
# Driven by the content directories themselves, so a new server
# version cannot be added and silently left unchecked.
for dir in content/server/*/; do
version=$(basename "$dir")
pages="${dir%/}/modules/admin_manual/pages/configuration/server"
if [ ! -d "$pages" ]; then
echo "::notice::$version has no configuration/server directory, nothing to check"
continue
fi
# git ls-remote exits 2 for "no such branch" and non-zero otherwise.
# Treating those alike would let a transient network failure resolve
# 10.16 to master and then fail the diff for a baffling reason.
rc=0
git ls-remote --exit-code --heads "$CORE_REPO" "$version" >/dev/null 2>&1 || rc=$?
case "$rc" in
0) ref="$version" ;;
2) ref=master ;;
*) echo "::error::cannot reach owncloud/core to resolve a branch for $version (git ls-remote exit $rc)"; exit 1 ;;
esac
echo "::group::$version (core $ref)"
fetch_core "$ref"
# Without a branch of its own, a version is either the one still in
# development on master, or a finished line that master has moved
# past - 11.0 once master became 11.1. A finished line gets no
# maintenance branch, so its last final release is the source.
# Anything else would be regenerated from the wrong source, so say
# so instead.
if [ "$ref" = master ]; then
core_version=$(sed -n 's/^$OC_VersionString = .\([0-9]*\.[0-9]*\).*/\1/p' ".core-$version/version.php")
if [ "$core_version" != "$version" ]; then
# Same reasoning as above: a network failure must not read as
# "no tags". Pre-releases are excluded, and they also sort
# above their final release.
if ! tags=$(git ls-remote --tags --refs --sort=-version:refname "$CORE_REPO" "refs/tags/v$version.*"); then
echo "::error::cannot reach owncloud/core to list the v$version.* tags"
exit 1
fi
ref=$(sed -n "s|.*refs/tags/\(v${version//./\\.}\.[0-9][0-9]*\)$|\1|p" <<< "$tags" | head -n 1)
if [ -z "$ref" ]; then
echo "::error::core has no $version branch, no v$version.N release and master is $core_version, so there is no source for content/server/$version"
exit 1
fi
echo "master is $core_version, so $version is regenerated from its last release, $ref"
fetch_core "$ref"
fi
fi
for pair in \
"config.sample.php:config_sample_php_parameters.adoc" \
"config.apps.sample.php:config_apps_sample_php_parameters.adoc"; do
sample=".core-$version/config/${pair%%:*}"
page="$pages/${pair#*:}"
if [ ! -r "$sample" ]; then
echo "::error::$sample is missing in core $ref - the converter would report success and change nothing"
exit 1
fi
# A page that exists in the other versions but not this one means
# either a deletion or a half-finished new version. If a version
# ever legitimately has only one, skip it explicitly rather than
# letting it pass unnoticed.
if [ ! -f "$page" ]; then
echo "::error::$page does not exist, so it cannot be verified"
exit 1
fi
# Keep the committed copy to compare against. The comparison
# deliberately does not use git: the pages are just files, and
# inside this container git cannot see the workspace repository.
mkdir -p "$RUNNER_TEMP/committed/$(dirname "$page")"
cp "$page" "$RUNNER_TEMP/committed/$page"
php .config-to-docs/convert.php config:convert-adoc \
--input-file="$sample" --output-file="$page"
generated=$((generated + 1))
done
rm -rf ".core-$version"
versions=$((versions + 1))
echo "::endgroup::"
done
if [ "$versions" -eq 0 ]; then
echo "::error::no server version was checked - has content/server/ moved?"
exit 1
fi
expected=$((versions * 2))
if [ "$generated" -ne "$expected" ]; then
echo "::error::regenerated $generated pages for $versions versions, expected $expected"
exit 1
fi
echo "Regenerated $generated pages across $versions versions."
- name: Fail if the committed pages differ from the generated output
run: |
set -eu
# diff, not git diff: see the note in the previous step. Each snapshot
# taken before regeneration is compared with the page as it now stands,
# so the diff reads committed -> generated, i.e. what needs applying.
: > "$RUNNER_TEMP/drift.diff"
drift=0
compared=0
while IFS= read -r snapshot; do
page="${snapshot#"$RUNNER_TEMP"/committed/}"
compared=$((compared + 1))
diff -u "$snapshot" "$page" \
--label "a/$page" --label "b/$page" >> "$RUNNER_TEMP/drift.diff" || drift=1
done < <(find "$RUNNER_TEMP/committed" -type f -name '*_sample_php_parameters.adoc' | sort)
if [ "$compared" -eq 0 ]; then
echo "::error::no snapshots to compare - the previous step cannot have run"
exit 1
fi
if [ "$drift" -eq 0 ]; then
echo "All $compared config parameter pages match the generator output."
exit 0
fi
{
echo "### Config parameter pages are out of sync"
echo
echo "These pages are generated by [config-to-docs](https://github.com/owncloud/config-to-docs)"
echo "from \`config/config.sample.php\` and \`config/config.apps.sample.php\` in"
echo "[owncloud/core](https://github.com/owncloud/core). Everything below the"
echo "\`header end\` marker is machine output."
echo
echo "* **To document a config key**, change its comment in core, then regenerate."
echo "* **To change a page's introduction**, edit *above* the marker - that part is kept."
echo "* **If core changed and the page is merely stale**, commit the regenerated page."
echo
echo "To regenerate locally: clone core and config-to-docs, check out the core ref"
echo "named in this job's log for the version, and run \`./ctd.sh\` in config-to-docs."
echo
echo '```diff'
cat "$RUNNER_TEMP/drift.diff"
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
echo "::error::Committed config parameter pages differ from config-to-docs output - see the job summary for the diff and how to fix it."
grep -E '^(---|\+\+\+|Only in)' "$RUNNER_TEMP/drift.diff" || true
exit 1
- name: Upload the regenerated pages
# So the fix can be downloaded rather than copy-pasted out of a log.
if: failure()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: regenerated-config-pages
path: content/server/*/modules/admin_manual/pages/configuration/server/config_*sample_php_parameters.adoc
if-no-files-found: ignore