Hugo 115.1 and PostCSS do not work well enough to be usable

using gitlab-ci.yml and hugo 0.115.1 I am unable to get a standard hugo install to build.

  1. Question: Why does it require --global when the identical gitlab-ci.yml file from MundoLibre doesn’t use --global when installing the same npm packages. His works, mine doesn’t work, and it only manages to appear to almost work slightly when I add --global. At least the packages become accessible. Postcss still doesn’t work, but it is accessible enough to demonstrate that it also doesn’t work.

Issue occurs across multiple versions of Hugo and postcss including the latest version of both.

package.json snippet:
“devDependencies”: {
“autoprefixer”: “^10.4.14”,
“hugo-extended”: “0.115.1”,
“postcss-cli”: “^10.1.0”,
“postcss”: “^8.4.25”

Using a nearly identical known working gitalb-ci.yml file from David Marzal / MundoLibre · GitLab

# https://gitlab.com/pages/hugo/-/blob/main/.gitlab-ci.yml
image: registry.gitlab.com/pages/hugo/hugo_extended:0.115.1
###image: registry.gitlab.com/pages/hugo/hugo_extended:0.100.2
# Esta imagen no tiene npm/yarn instalado, pero si apk

variables:
  HUGO_ENV: production
  THEME_URL: "github.com/google/docsy@v0.7.1"
  CI_DEBUG_TRACE: "true"

default:
  before_script:
    #- apk update && apk upgrade
    - apk add --no-cache git go npm brotli
    #- apk add --no-cache --update optipng jpegoptim
    #-hugo mod init gitlab.com/Marzal/mundolibre.gitlab.io # Falla con los modulos de hugo en la config 
    - hugo mod get $THEME_URL
    #- hugo mod graph # Comprobar modulos
    #- yarn add postcss postcss-cli autoprefixer --dev 
    - npm install --global postcss postcss-cli autoprefixer #--save-dev
    - npm list --depth=0
    # https://www.npmjs.com/package/hugo-extended

test:
  script:
    - hugo
  rules:
    - if: $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH

pages:
  script:
    - hugo --minify
    - find public -type f -regex '.*\.\(htm\|html\|txt\|text\|js\|css\|json\)$' -exec brotli -f -k {} \;
    - find public -type f -regex '.*\.\(xml\|ttf\|svg\)$' -exec brotli -f -k {} \;
    #- find public/ -type f -name "*.jpg" -exec jpegoptim -q -m90 --strip-all --all-progressive {} \;
    #- find public/ -type f -name "*.png" -exec optipng -o5 -strip all -quiet {} \;

  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH

pipeline job log errors when trying to list installed npm packages:

$ hugo mod get $THEME_URL
+ hugo mod get github.com/google/docsy@v0.7.1
hugo: downloading modules …
hugo: collected modules in 24577 ms
+ echo '$ npm install --global postcss postcss-cli autoprefixer'
$ npm install --global postcss postcss-cli autoprefixer
+ npm install --global postcss postcss-cli autoprefixer
added 77 packages, and audited 78 packages in 7s
19 packages are looking for funding
  run `npm fund` for details
found 0 vulnerabilities
+ echo '$ npm ls'
$ npm ls
+ npm ls
docsy-example-site@0.7.1 /builds/pages/docs
+-- ansi-styles@4.3.0 extraneous
+-- argparse@1.0.10 extraneous
+-- array-union@2.1.0 extraneous
+-- at-least-node@1.0.0 extraneous
+-- autoprefixer@10.4.14
+-- caller-callsite@2.0.0 extraneous
+-- caller-path@2.0.0 extraneous
+-- callsites@2.0.0 extraneous
+-- camelcase@5.3.1 extraneous
+-- chalk@5.3.0 extraneous
+-- color-convert@2.0.1 extraneous
+-- color-name@1.1.4 extraneous
+-- colorette@1.2.1 extraneous
+-- cosmiconfig@5.2.1 extraneous
+-- decamelize@1.2.0 extraneous
+-- error-ex@1.3.2 extraneous
+-- escape-string-regexp@1.0.5 extraneous
+-- esprima@4.0.1 extraneous
+-- find-up@6.3.0 extraneous
+-- has-flag@3.0.0 extraneous
+-- UNMET DEPENDENCY hugo-extended@0.115.1
+-- import-cwd@2.1.0 extraneous
+-- import-fresh@2.0.0 extraneous
+-- import-from@2.1.0 extraneous
+-- is-arrayish@0.2.1 extraneous
+-- is-directory@0.3.1 extraneous
+-- js-yaml@3.14.0 extraneous
+-- json-parse-better-errors@1.0.2 extraneous
+-- locate-path@7.2.0 extraneous
+-- lodash@4.17.21 extraneous
+-- log-symbols@5.1.0 extraneous
+-- num2fraction@1.2.2 extraneous
+-- p-limit@4.0.0 extraneous
+-- p-locate@6.0.0 extraneous
+-- p-try@2.2.0 extraneous
+-- parse-json@5.2.0 extraneous
+-- path-exists@5.0.0 extraneous
+-- postcss-cli@10.1.0
+-- postcss@8.4.25
+-- require-main-filename@2.0.0 extraneous
+-- resolve-from@3.0.0 extraneous
+-- set-blocking@2.0.0 extraneous
+-- sprintf-js@1.0.3 extraneous
`-- which-module@2.0.0 extraneous
npm ERR! code ELSPROBLEMS
npm ERR! extraneous: ansi-styles@4.3.0 /builds/pages/docs/node_modules/ansi-styles
npm ERR! extraneous: argparse@1.0.10 /builds/pages/docs/node_modules/argparse
npm ERR! extraneous: array-union@2.1.0 /builds/pages/docs/node_modules/array-union
npm ERR! extraneous: at-least-node@1.0.0 /builds/pages/docs/node_modules/at-least-node
npm ERR! extraneous: caller-callsite@2.0.0 /builds/pages/docs/node_modules/caller-callsite
npm ERR! extraneous: caller-path@2.0.0 /builds/pages/docs/node_modules/caller-path
npm ERR! extraneous: callsites@2.0.0 /builds/pages/docs/node_modules/callsites
npm ERR! extraneous: camelcase@5.3.1 /builds/pages/docs/node_modules/camelcase
npm ERR! extraneous: chalk@5.3.0 /builds/pages/docs/node_modules/chalk
npm ERR! extraneous: color-convert@2.0.1 /builds/pages/docs/node_modules/color-convert
npm ERR! extraneous: color-name@1.1.4 /builds/pages/docs/node_modules/color-name
npm ERR! extraneous: colorette@1.2.1 /builds/pages/docs/node_modules/colorette
npm ERR! extraneous: cosmiconfig@5.2.1 /builds/pages/docs/node_modules/cosmiconfig
npm ERR! extraneous: decamelize@1.2.0 /builds/pages/docs/node_modules/decamelize
npm ERR! extraneous: error-ex@1.3.2 /builds/pages/docs/node_modules/error-ex
npm ERR! extraneous: escape-string-regexp@1.0.5 /builds/pages/docs/node_modules/escape-string-regexp
npm ERR! extraneous: esprima@4.0.1 /builds/pages/docs/node_modules/esprima
npm ERR! extraneous: find-up@6.3.0 /builds/pages/docs/node_modules/find-up
npm ERR! extraneous: has-flag@3.0.0 /builds/pages/docs/node_modules/has-flag
npm ERR! missing: hugo-extended@0.115.1, required by docsy-example-site@0.7.1
npm ERR! extraneous: import-cwd@2.1.0 /builds/pages/docs/node_modules/import-cwd
npm ERR! extraneous: import-fresh@2.0.0 /builds/pages/docs/node_modules/import-fresh
npm ERR! extraneous: import-from@2.1.0 /builds/pages/docs/node_modules/import-from
npm ERR! extraneous: is-arrayish@0.2.1 /builds/pages/docs/node_modules/is-arrayish
npm ERR! extraneous: is-directory@0.3.1 /builds/pages/docs/node_modules/is-directory
npm ERR! extraneous: js-yaml@3.14.0 /builds/pages/docs/node_modules/js-yaml
npm ERR! extraneous: json-parse-better-errors@1.0.2 /builds/pages/docs/node_modules/json-parse-better-errors
npm ERR! extraneous: locate-path@7.2.0 /builds/pages/docs/node_modules/locate-path
npm ERR! extraneous: lodash@4.17.21 /builds/pages/docs/node_modules/lodash
npm ERR! extraneous: log-symbols@5.1.0 /builds/pages/docs/node_modules/log-symbols
npm ERR! extraneous: num2fraction@1.2.2 /builds/pages/docs/node_modules/num2fraction
npm ERR! extraneous: p-limit@4.0.0 /builds/pages/docs/node_modules/p-limit
npm ERR! extraneous: p-locate@6.0.0 /builds/pages/docs/node_modules/p-locate
npm ERR! extraneous: p-try@2.2.0 /builds/pages/docs/node_modules/p-try
npm ERR! extraneous: parse-json@5.2.0 /builds/pages/docs/node_modules/parse-json
npm ERR! extraneous: path-exists@5.0.0 /builds/pages/docs/node_modules/path-exists
npm ERR! extraneous: require-main-filename@2.0.0 /builds/pages/docs/node_modules/require-main-filename
npm ERR! extraneous: resolve-from@3.0.0 /builds/pages/docs/node_modules/resolve-from
npm ERR! extraneous: set-blocking@2.0.0 /builds/pages/docs/node_modules/set-blocking
npm ERR! extraneous: sprintf-js@1.0.3 /builds/pages/docs/node_modules/sprintf-js
npm ERR! extraneous: which-module@2.0.0 /builds/pages/docs/node_modules/which-module
npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2023-07-18T15_20_37_049Z-debug-0.log

pipeline also errors when attempting to prune unneeded packages and I believe the reason for that is that it expects me to hand type all the unneeded packages which it labels as extraneous… Not gonna do it.

Let’s ignore for now the following questions:

1.Why does the npm ls command generate an error?
2. Why does the npm list --depth=0 command generate an error?

Let’s answer the question:
Why does postcss need to find the vendor directory and fail on my gitlab repo but not on MundoLibre?

Start building sites … 
hugo v0.115.1+extended linux/amd64 BuildDate=unknown
WARN  .File.UniqueID on zero object. Wrap it in if or with: {{ with .File }}{{ .UniqueID }}{{ end }}
Total in 5289 ms
Error: error building site: POSTCSS: failed to transform "scss/main.css" (text/css): Error: Cannot find module './vendor'
Require stack:
- /builds/pages/docs/node_modules/autoprefixer/lib/prefixes.js
- /builds/pages/docs/node_modules/autoprefixer/lib/autoprefixer.js
- /builds/pages/docs/postcss.config.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:955:15)
    at Module._load (node:internal/modules/cjs/loader:803:27)
    at Module.require (node:internal/modules/cjs/loader:1021:19)
    at require (node:internal/modules/cjs/helpers:103:18)
    at Object.<anonymous> (/builds/pages/docs/node_modules/autoprefixer/lib/prefixes.js:1:14)
    at Module._compile (node:internal/modules/cjs/loader:1119:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1173:10)
    at Module.load (node:internal/modules/cjs/loader:997:32)
    at Module._load (node:internal/modules/cjs/loader:838:12)
    at Module.require (node:internal/modules/cjs/loader:1021:19) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/builds/pages/docs/node_modules/autoprefixer/lib/prefixes.js',
    '/builds/pages/docs/node_modules/autoprefixer/lib/autoprefixer.js',
    '/builds/pages/docs/postcss.config.js'
  ]
}

I have used Hugo >= 0.115.1 with great success with TailwindCSS and PostCSS, so I would claim that it can be usable. I don’t know your setup in detail, so that I will leave up to others.

I don’t use any global NPM installs, though.

To rule out any environmental issues, could you try to

  1. git clone GitHub - bep/hugo-starter-tailwind-basic: A basic and simple to set up Hugo with TailwindCSS starter project.
  2. cd hugo-starter-tailwind-basic
  3. npm ci
  4. hugo server

I just tested the above on my MacBook and that works great for me.

1 Like

This GitLab workflow:

  • Gets a Hugo Module
  • Transpiles Sass to CSS using Dart Sass
  • Uses PostCSS to auto-prefix
  • Compresses published files using gzip and brotli

https://gitlab.com/jmooring/hosting-gitlab-pages/-/blob/main/.gitlab-ci.yml

Works great.

DART_SASS_VERSION: 1.63.6
HUGO_VERSION: 0.115.3
NODE_VERSION: 20.x
1 Like

So the following slightly modified gitlab-ci.yml from the above very helpful example file generates a slightly different error when attempting to use postcss:


variables:
  HUGO_ENV: production
  THEME_URL: "github.com/google/docsy@v0.7.1"
  CI_DEBUG_TRACE: "true"
  DART_SASS_VERSION: 1.63.6
  HUGO_VERSION: 0.115.3
  NODE_VERSION: 20.x
  GIT_DEPTH: 0
  GIT_STRATEGY: clone
  GIT_SUBMODULE_STRATEGY: recursive
  TZ: Europe/Vienna
  CI_DEBUG_TRACE: "true"

image:
  name: golang:1.20.6-bookworm

pages:
  script:
    # Install brotli
    - apt-get update
    - apt-get install -y brotli
    # Install Dart Sass
    - curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz
    - tar -xf dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz
    - cp -r dart-sass/* /usr/local/bin
    - rm -rf dart-sass*
    # Install Hugo
    - curl -LJO https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb
    - apt-get install -y ./hugo_extended_${HUGO_VERSION}_linux-amd64.deb
    - rm hugo_extended_${HUGO_VERSION}_linux-amd64.deb
    # Install Node.js
    - curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION} | bash -
    - pwd
    - apt-get install -y nodejs
    # Install Node.js dependencies
    - "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true"
    - ls -alF ./node_modules/
    # Build
    - hugo mod get $THEME_URL
    - hugo --gc --minify
    # Compress
    - find public -type f -regex '.*\.\(css\|html\|js\|txt\|xml\)$' -exec gzip -f -k {} \;
    - find public -type f -regex '.*\.\(css\|html\|js\|txt\|xml\)$' -exec brotli -f -k {} \;
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

And the pipeline output ends with:

++ echo '$ apt-get update'
++ apt-get update
$ apt-get update
Get:1 http://deb.debian.org/debian bookworm InRelease [147 kB]
Get:2 http://deb.debian.org/debian bookworm-updates InRelease [52.1 kB]
Get:3 http://deb.debian.org/debian-security bookworm-security InRelease [48.0 kB]
Get:4 http://deb.debian.org/debian bookworm/main amd64 Packages [8904 kB]
Get:5 http://deb.debian.org/debian bookworm-updates/main amd64 Packages [4732 B]
Get:6 http://deb.debian.org/debian-security bookworm-security/main amd64 Packages [48.0 kB]
Fetched 9204 kB in 3s (3429 kB/s)
Reading package lists...
++ echo '$ apt-get install -y brotli'
$ apt-get install -y brotli
++ apt-get install -y brotli
Reading package lists...
Building dependency tree...
Reading state information...
The following NEW packages will be installed:
  brotli
0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
Need to get 277 kB of archives.
After this operation, 788 kB of additional disk space will be used.
Get:1 http://deb.debian.org/debian bookworm/main amd64 brotli amd64 1.0.9-2+b6 [277 kB]
debconf: delaying package configuration, since apt-utils is not installed
Fetched 277 kB in 0s (1109 kB/s)
Selecting previously unselected package brotli.
(Reading database ... 15610 files and directories currently installed.)
Preparing to unpack .../brotli_1.0.9-2+b6_amd64.deb ...
Unpacking brotli (1.0.9-2+b6) ...
Setting up brotli (1.0.9-2+b6) ...
++ echo '$ curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz'
$ curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz
++ curl -LJO https://github.com/sass/dart-sass/releases/download/1.63.6/dart-sass-1.63.6-linux-x64.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 3665k  100 3665k    0     0  8681k      0 --:--:-- --:--:-- --:--:-- 8681k
++ echo '$ tar -xf dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz'
$ tar -xf dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz
++ tar -xf dart-sass-1.63.6-linux-x64.tar.gz
++ echo '$ cp -r dart-sass/* /usr/local/bin'
$ cp -r dart-sass/* /usr/local/bin
++ cp -r dart-sass/sass dart-sass/src /usr/local/bin
++ echo '$ rm -rf dart-sass*'
$ rm -rf dart-sass*
++ rm -rf dart-sass dart-sass-1.63.6-linux-x64.tar.gz
++ echo '$ curl -LJO https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb'
$ curl -LJO https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb
++ curl -LJO https://github.com/gohugoio/hugo/releases/download/v0.115.3/hugo_extended_0.115.3_linux-amd64.deb
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 19.0M  100 19.0M    0     0  18.9M      0  0:00:01  0:00:01 --:--:-- 33.0M
++ echo '$ apt-get install -y ./hugo_extended_${HUGO_VERSION}_linux-amd64.deb'
$ apt-get install -y ./hugo_extended_${HUGO_VERSION}_linux-amd64.deb
++ apt-get install -y ./hugo_extended_0.115.3_linux-amd64.deb
Reading package lists...
Building dependency tree...
Reading state information...
The following NEW packages will be installed:
  hugo
0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
Need to get 0 B/20.0 MB of archives.
After this operation, 59.1 MB of additional disk space will be used.
Get:1 /builds/pages/docs/hugo_extended_0.115.3_linux-amd64.deb hugo amd64 0.115.3 [20.0 MB]
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package hugo.
(Reading database ... 15616 files and directories currently installed.)
Preparing to unpack .../hugo_extended_0.115.3_linux-amd64.deb ...
Unpacking hugo (0.115.3) ...
Setting up hugo (0.115.3) ...
++ echo '$ rm hugo_extended_${HUGO_VERSION}_linux-amd64.deb'
$ rm hugo_extended_${HUGO_VERSION}_linux-amd64.deb
++ rm hugo_extended_0.115.3_linux-amd64.deb
++ echo '$ curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION} | bash -'
$ curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION} | bash -
++ bash -
++ curl -fsSL https://deb.nodesource.com/setup_20.x
## Installing the NodeSource Node.js 20.x repo...
## Populating apt-get cache...
+ apt-get update
Hit:1 http://deb.debian.org/debian bookworm InRelease
Hit:2 http://deb.debian.org/debian bookworm-updates InRelease
Hit:3 http://deb.debian.org/debian-security bookworm-security InRelease
Reading package lists...
## Installing packages required for setup: lsb-release...
+ apt-get install -y lsb-release > /dev/null 2>&1
## Confirming "bookworm" is supported...
+ curl -sLf -o /dev/null 'https://deb.nodesource.com/node_20.x/dists/bookworm/Release'
## Adding the NodeSource signing key to your keyring...
+ curl -s https://deb.nodesource.com/gpgkey/nodesource.gpg.key | gpg --dearmor | tee /usr/share/keyrings/nodesource.gpg >/dev/null
## Creating apt sources list file for the NodeSource Node.js 20.x repo...
+ echo 'deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x bookworm main' > /etc/apt/sources.list.d/nodesource.list
+ echo 'deb-src [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x bookworm main' >> /etc/apt/sources.list.d/nodesource.list
## Running `apt-get update` for you...
+ apt-get update
Hit:1 http://deb.debian.org/debian bookworm InRelease
Hit:2 http://deb.debian.org/debian bookworm-updates InRelease
Get:3 https://deb.nodesource.com/node_20.x bookworm InRelease [4586 B]
Hit:4 http://deb.debian.org/debian-security bookworm-security InRelease
Get:5 https://deb.nodesource.com/node_20.x bookworm/main amd64 Packages [776 B]
Fetched 5362 B in 0s (22.5 kB/s)
Reading package lists...
## Run `sudo apt-get install -y nodejs` to install Node.js 20.x and npm
## You may also need development tools to build native addons:
     sudo apt-get install gcc g++ make
## To install the Yarn package manager, run:
     curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | sudo tee /usr/share/keyrings/yarnkey.gpg >/dev/null
     echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
     sudo apt-get update && sudo apt-get install yarn
++ echo '$ pwd'
$ pwd
++ pwd
/builds/pages/docs
++ echo '$ apt-get install -y nodejs'
$ apt-get install -y nodejs
++ apt-get install -y nodejs
Reading package lists...
Building dependency tree...
Reading state information...
The following NEW packages will be installed:
  nodejs
0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
Need to get 30.3 MB of archives.
After this operation, 194 MB of additional disk space will be used.
Get:1 https://deb.nodesource.com/node_20.x bookworm/main amd64 nodejs amd64 20.4.0-deb-1nodesource1 [30.3 MB]
debconf: delaying package configuration, since apt-utils is not installed
Fetched 30.3 MB in 1s (31.2 MB/s)
Selecting previously unselected package nodejs.
(Reading database ... 15624 files and directories currently installed.)
Preparing to unpack .../nodejs_20.4.0-deb-1nodesource1_amd64.deb ...
Unpacking nodejs (20.4.0-deb-1nodesource1) ...
Setting up nodejs (20.4.0-deb-1nodesource1) ...
++ echo '$ [[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true'
$ [[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true
++ [[ -f package-lock.json ]]
++ [[ -f npm-shrinkwrap.json ]]
++ true
++ echo '$ ls -alF ./node_modules/'
$ ls -alF ./node_modules/
++ ls -alF ./node_modules/
total 528
drwxrwxrwx 107 root root  4096 Jul 19 12:08 ./
drwxrwxrwx  14 root root  4096 Jul 19 12:08 ../
drwxrwxrwx   2 root root  4096 Jul 19 12:08 .bin/
-rw-rw-rw-   1 root root 84865 Jul 19 12:08 .package-lock.json
drwxrwxrwx   5 root root  4096 Jul 19 12:08 @nodelib/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 ansi-regex/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 ansi-styles/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 anymatch/
drwxrwxrwx   3 root root  4096 Jul 19 12:08 argparse/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 array-union/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 at-least-node/
drwxrwxrwx   6 root root  4096 Jul 19 12:08 autoprefixer/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 binary-extensions/
drwxrwxrwx   3 root root  4096 Jul 19 12:08 braces/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 browserslist/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 caller-callsite/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 caller-path/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 callsites/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 camelcase/
drwxrwxrwx   4 root root  4096 Jul 19 12:08 caniuse-lite/
drwxrwxrwx   4 root root  4096 Jul 19 12:08 chalk/
drwxrwxrwx   4 root root  4096 Jul 19 12:08 chokidar/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 cliui/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 color-convert/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 color-name/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 colorette/
drwxrwxrwx   3 root root  4096 Jul 19 12:08 cosmiconfig/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 decamelize/
drwxrwxrwx   4 root root  4096 Jul 19 12:08 dependency-graph/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 dir-glob/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 electron-to-chromium/
drwxrwxrwx   3 root root  4096 Jul 19 12:08 emoji-regex/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 error-ex/
drwxrwxrwx   4 root root  4096 Jul 19 12:08 escalade/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 escape-string-regexp/
drwxrwxrwx   4 root root  4096 Jul 19 12:08 esprima/
drwxrwxrwx   3 root root  4096 Jul 19 12:08 fast-glob/
drwxrwxrwx   4 root root  4096 Jul 19 12:08 fastq/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 fill-range/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 find-up/
drwxrwxrwx   3 root root  4096 Jul 19 12:08 fs-extra/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 get-caller-file/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 get-stdin/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 glob-parent/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 globby/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 graceful-fs/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 has-flag/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 ignore/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 import-cwd/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 import-fresh/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 import-from/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 is-arrayish/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 is-binary-path/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 is-directory/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 is-extglob/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 is-fullwidth-code-point/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 is-glob/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 is-number/
drwxrwxrwx   5 root root  4096 Jul 19 12:08 js-yaml/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 json-parse-better-errors/
drwxrwxrwx   3 root root  4096 Jul 19 12:08 jsonfile/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 locate-path/
drwxrwxrwx   3 root root 20480 Jul 19 12:08 lodash/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 log-symbols/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 merge2/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 micromatch/
drwxrwxrwx   6 root root  4096 Jul 19 12:08 nanoid/
drwxrwxrwx   3 root root  4096 Jul 19 12:08 node-releases/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 normalize-path/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 normalize-range/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 num2fraction/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 p-limit/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 p-locate/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 p-try/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 parse-json/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 path-exists/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 path-type/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 picocolors/
drwxrwxrwx   3 root root  4096 Jul 19 12:08 picomatch/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 pify/
drwxrwxrwx   3 root root  4096 Jul 19 12:08 postcss/
drwxrwxrwx   5 root root  4096 Jul 19 12:08 postcss-cli/
drwxrwxrwx   3 root root  4096 Jul 19 12:08 postcss-load-config/
drwxrwxrwx   4 root root  4096 Jul 19 12:08 postcss-reporter/
drwxrwxrwx   3 root root  4096 Jul 19 12:08 postcss-value-parser/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 pretty-hrtime/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 read-cache/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 readdirp/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 require-directory/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 require-main-filename/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 resolve-from/
drwxrwxrwx   3 root root  4096 Jul 19 12:08 reusify/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 run-parallel/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 set-blocking/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 slash/
drwxrwxrwx   4 root root  4096 Jul 19 12:08 source-map/
drwxrwxrwx   3 root root  4096 Jul 19 12:08 source-map-js/
drwxrwxrwx   6 root root  4096 Jul 19 12:08 sprintf-js/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 string-width/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 strip-ansi/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 to-regex-range/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 universalify/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 update-browserslist-db/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 which-module/
drwxrwxrwx   3 root root  4096 Jul 19 12:08 wrap-ansi/
drwxrwxrwx   2 root root  4096 Jul 19 12:08 y18n/
drwxrwxrwx   4 root root  4096 Jul 19 12:08 yargs/
drwxrwxrwx   3 root root  4096 Jul 19 12:08 yargs-parser/
++ echo '$ hugo mod get $THEME_URL'
$ hugo mod get $THEME_URL
++ hugo mod get github.com/google/docsy@v0.7.1
hugo: downloading modules …
hugo: collected modules in 22066 ms
++ echo '$ hugo --gc --minify'
$ hugo --gc --minify
++ hugo --gc --minify
Start building sites … 
hugo v0.115.3-5c2e014a5150553a9fa4f9c1eb7dc4db89c0f1ab+extended linux/amd64 BuildDate=2023-07-13T16:11:34Z VendorInfo=gohugoio
WARN  .File.UniqueID on zero object. Wrap it in if or with: {{ with .File }}{{ .UniqueID }}{{ end }}
Total in 4334 ms
Error: error building site: POSTCSS: failed to transform "scss/main.css" (text/css): sh: 1: postcss: Permission denied
Cleaning up project directory and file based variables
00:00
+ grep pipefail
+ set -o
+ set -o pipefail
+ set -o errexit
+ set +o noclobber
+ eval '$'\''rm'\'' -f /builds/pages/docs.tmp/CI_SERVER_TLS_CA_FILE
'
++ rm -f /builds/pages/docs.tmp/CI_SERVER_TLS_CA_FILE
+ :
+ exit 0
ERROR: Job failed: exit code 1

So if you take the error message:

Error: error building site: POSTCSS: failed to transform "scss/main.css" (text/css): sh: 1: postcss: Permission denied

at face value, the root user cannot transform some scss/main.css since it does not have the execute permission set. Which is a hard to swallow fact since the same permissions on the local build work great no problem incidentally the user on the local build is vscode:vscode in a devcontainer and here we are in a docker container as root:root.

Long story short, the pipeline definitely executes as the root user and the root user definitely could potentially use postcss but whatever happens inside the hugo black box appears to either trigger a spurious error message or the build isn’t executing things as the root user when it tries to access postcss.
So to summarize:

  1. I can use known working gitlab-ci.yml files from working sites and generate astonishingly similar failures on the gitlab system I am using.
  2. All the errors revolve around postcss and occur using the most current versions of hugo and postcss.
  3. The error is either "missing ./vendor directory", “no permission”, or “this feature is not available in your current Hugo version”

Checking now to see the permissions on /scss/main.css…
assuming the error message is referring to /public/scss/ seems obvious except there is no main.css in that directory. Perhaps /themes/docsy/assets/scss
At any rate, the /themes/docsy/assets/scss/main.css file shouldn’t need rwx for root to build the hugo site. Perhaps trying each version of docsy moving backwards until the error disappears to the next thing…

Progress!
If I begin the build by deleting all the node modules:

    - rm -rf ./node_modules

I can resolve the permission denied error and get back to the good old error about not being able to use postcss with this version of hugo (the latest). Its a spurious error message but a more common one!

" Error: error building site: POSTCSS: failed to transform "scss/main.css" (text/css). Check your PostCSS installation; install with "npm install postcss-cli". See https://gohugo.io/hugo-pipes/postcss/: this feature is not available in your current Hugo version, see https://goo.gl/YMrWcn for more information

[1273](https://gitlab.omis.at/pages/docs/-/jobs/10597#L1273)Cleaning up project directory and file based variables

If you think the error message is useful:

Error: error building site: POSTCSS: failed to transform "scss/main.css" (text/css). Check your PostCSS installation; install with "npm install postcss-cli". See https://gohugo.io/hugo-pipes/postcss/: this feature is not available in your current Hugo version, see https://goo.gl/YMrWcn for more information

Think again. npm install postcss-cli could be added to the .gitlab-ci.yml file but the pipeline will still fail:
And in terms of conveying meaning the error message is vague, it expects the user to do 3 things:

  1. check the installation of postcss which is vague enough to be ignored.
  2. After pretending to check the installation it requests that the user also install postcss-cli which is maybe or maybe not the exact same thing?!?
  3. And after you do those two vague steps it reminds you that no matter what, the feature is unavailable for this version of hugo anyway so you just wasted 2 steps. And the helpful link just reminds you that hugo and hugo_extended are two different things. Its a choose-your-own-adventure masquerading as an error message…

This is a real head-scratcher since I am fairly certain the error message was originally intended to point folks who have installed hugo to hugo_extended which I am very definitely using.

Attempts to use something innocuous like:
npm install postcss postcss-cli autoprefixer generate the following error in the pipeline:

++ echo '$ npm install postcss postcss-cli autoprefixer'
$ npm install postcss postcss-cli autoprefixer
++ npm install postcss postcss-cli autoprefixer
npm ERR! code 1
npm ERR! path /builds/pages/docs/node_modules/hugo-extended
npm ERR! command failed
npm ERR! command sh -c node postinstall.js
npm ERR! ✔ Hugo installed successfully!
npm ERR! ✖ Hugo installation failed. :(

Those last two lines make me wonder if someone from SAP wrote this code.
I need to install these globally. I don’t know why, but it seems to be so…

ok Final secret sauce was deleting the packages.json file and pasting in the original from docsy 0.7.1 and then adding to the .gitlab-ci.yml from jmooring the following line to install the required packages globally. Incendentally this installs hugo into a golang image and ignores gitlab’s image registry altogether…

npm install -g postcss postcss-cli autoprefixer

See entire working pipeline file:

variables:
  HUGO_ENV: production
  THEME_URL: "github.com/google/docsy@v0.7.1"
  CI_DEBUG_TRACE: "true"
  DART_SASS_VERSION: 1.63.6
  HUGO_VERSION: 0.115.3
  NODE_VERSION: 20.x
  GIT_DEPTH: 0
  GIT_STRATEGY: clone
  GIT_SUBMODULE_STRATEGY: recursive
  TZ: Europe/Vienna
  CI_DEBUG_TRACE: "true"

image:
  name: golang:1.20.6-bookworm

pages:
  script:
    # Install brotli
    - rm -rf ./node_modules
    - apt-get update
    - apt-get install -y brotli
    # Install Dart Sass
    - curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz
    - tar -xf dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz
    - cp -r dart-sass/* /usr/local/bin
    - rm -rf dart-sass*
    # Install Hugo
    - curl -LJO https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb
    - apt-get install -y ./hugo_extended_${HUGO_VERSION}_linux-amd64.deb
    - rm hugo_extended_${HUGO_VERSION}_linux-amd64.deb
    # Install Node.js
    - curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION} | bash -
    - pwd
    - apt-get install -y nodejs
    - npm install -g postcss postcss-cli autoprefixer
    # Install Node.js dependencies
    - "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true"
    # Build
    - hugo mod get $THEME_URL
    - hugo --gc --minify
    # Compress
    - find public -type f -regex '.*\.\(css\|html\|js\|txt\|xml\)$' -exec gzip -f -k {} \;
    - find public -type f -regex '.*\.\(css\|html\|js\|txt\|xml\)$' -exec brotli -f -k {} \;
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.