build: Introduce node_modules/ as submodule

Build and maintain the node_modules/ as a submodule, using the
tools/node-modules script as it's done in the cockpit repo.

Introduce some helper workflows around it, all copied from cockpit
project.
This commit is contained in:
Katerina Koukiou 2025-02-28 16:10:45 +01:00
parent 4c3350e41b
commit 5502565138
8 changed files with 220 additions and 6 deletions

93
.github/workflows/dependabot.yml vendored Normal file
View file

@ -0,0 +1,93 @@
name: update node_modules
on:
pull_request_target:
types: [opened, reopened, synchronize, labeled]
jobs:
dependabot:
environment: npm-update
permissions:
contents: read
pull-requests: write
timeout-minutes: 5
runs-on: ubuntu-latest
if: ${{ contains(github.event.pull_request.labels.*.name, 'node_modules') }}
steps:
- name: Clone repository
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
fetch-depth: 0
- name: Clear node_modules label
uses: actions/github-script@v7
with:
script: |
try {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
name: 'node_modules'
});
} catch (e) {
if (e.name == 'HttpError' && e.status == 404) {
/* expected: 404 if label is unset */
} else {
throw e;
}
}
- name: Rebase pull request and drop node_modules changes
run: |
set -x
git config --global user.name "GitHub Workflow"
git config --global user.email "cockpituous@cockpit-project.org"
git fetch origin main:main
if ! git rebase main; then
git reset node_modules
GIT_EDITOR=true git rebase --continue
git show --stat
fi
- name: Update node_modules for package.json changes
run: |
make tools/node-modules
git config --global user.name "GitHub Workflow"
git config --global user.email "cockpituous@cockpit-project.org"
eval $(ssh-agent)
ssh-add - <<< '${{ secrets.NODE_CACHE_DEPLOY_KEY }}'
./tools/node-modules install
./tools/node-modules push
git add node_modules
ssh-add -D
ssh-agent -k
- name: Clear [no-test] prefix from PR title
if: ${{ contains(github.event.pull_request.title, '[no-test]') }}
uses: actions/github-script@v7
env:
TITLE: '${{ github.event.pull_request.title }}'
with:
script: |
const title = process.env['TITLE'].replace(/\[no-test\]\W+ /, '')
await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
title,
});
- name: Force push node_modules update
run: |
# Dependabot prefixes the commit with [no-test] which we don't want to keep in the commit
title=$(git show --pretty="%s" -s | sed -E "s/\[no-test\]\W+ //")
body=$(git show -s --pretty="%b")
git commit --amend -m "${title}" -m "${body}" --no-edit node_modules
eval $(ssh-agent)
ssh-add - <<< '${{ secrets.SELF_DEPLOY_KEY }}'
git push --force 'git@github.com:${{ github.repository }}' '${{ github.head_ref }}'
ssh-add -D
ssh-agent -k

View file

@ -33,3 +33,36 @@ jobs:
uses: cockpit-project/action-release@88d994da62d1451c7073e26748c18413fcdf46e9
with:
filename: "anaconda-webui-${{ github.ref_name }}.tar.xz"
node-cache:
# doesn't depend on it, but let's make sure the build passes before we do this
needs: [source]
runs-on: ubuntu-latest
environment: node-cache
# done via deploy key, token needs no write permissions at all
permissions: {}
steps:
- name: Clone repository
uses: actions/checkout@v4
- name: Set up git
run: |
git config user.name "GitHub Workflow"
git config user.email "cockpituous@cockpit-project.org"
- name: Tag node-cache
run: |
set -eux
# this is a shared repo, prefix with project name
TAG="${GITHUB_REPOSITORY#*/}-$(basename $GITHUB_REF)"
make tools/node-modules
tools/node-modules checkout
cd node_modules
git tag "$TAG"
git remote add cache "ssh://git@github.com/${GITHUB_REPOSITORY%/*}/node-cache"
eval $(ssh-agent)
ssh-add - <<< '${{ secrets.DEPLOY_KEY }}'
# make this idempotent: delete an existing tag
git push cache :"$TAG" || true
git push cache tag "$TAG"
ssh-add -D

65
.github/workflows/reposchutz.yml vendored Normal file
View file

@ -0,0 +1,65 @@
name: repository
on:
pull_request_target:
types: [opened, reopened, synchronize, labeled, unlabeled]
jobs:
check:
name: Protection checks
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
timeout-minutes: 5
env:
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
BASE_SHA: ${{ github.event.pull_request.base.sha }}
steps:
- name: Clone target branch
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Fetch PR commits
run: git fetch origin "${BASE_SHA}" "${HEAD_SHA}"
- name: Clear .github-changes label
if: ${{ !endsWith(github.event.action, 'labeled') }}
uses: actions/github-script@v7
with:
script: |
try {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
name: '.github-changes'
});
} catch (e) {
if (e.name == 'HttpError' && e.status == 404) {
/* expected: 404 if label is unset */
} else {
throw e;
}
}
- name: Check for .github changes
# We want to run this check any time the .github-changes label is not
# set, which needs to include the case where we just unset it above.
if: ${{ !endsWith(github.event.action, 'labeled') ||
!contains(github.event.pull_request.labels.*.name, '.github-changes') }}
run: |
set -x
git log --full-history --exit-code --patch "${HEAD_SHA}" --not "${BASE_SHA}" -- .github >&2
- name: Check for node_modules availability and package.json consistency
run: |
# Make tools/node-modules available
make tools/node-modules
# for each commit in the PR which modifies package.json or node_modules...
for commit in $(git log --reverse --full-history --format=%H \
"${HEAD_SHA}" --not "${BASE_SHA}" -- package.json node_modules); do
# ... check that package.json and node_modules/.package.json are in sync
tools/node-modules verify "${commit}"
done

1
.gitignore vendored
View file

@ -19,7 +19,6 @@
/bots
/anaconda-webui-*.tar.xz
/dist
/node_modules
/package-lock.json
/pkg
/tmp/

3
.gitmodules vendored
View file

@ -2,3 +2,6 @@
path = test/reference
url = https://github.com/rhinstaller/pixel-test-reference
branch = empty
[submodule "node_modules"]
path = node_modules
url = https://github.com/rhinstaller/node-cache

View file

@ -84,3 +84,21 @@ as described in `<test/README.rst>`_.
Then you can run::
make rsync
Updating `node_modules`
----------------------
Before making any changes, ensure the following environment variable is set::
GITHUB_BASE="rhinstaller/anaconda-webui"
If you need to update package.json — for example, to add or remove a dependency — run::
tools/node-modules install
This command regenerates the node_modules cache based on your updated package.json using npm install.
Note: Your locally rebuilt changes to `node_modules` won't be used by others. A new
version will be created by a GitHub workflow when you open your pull request.
For more details, see the `Cockpit HACKING.md guide <https://github.com/cockpit-project/cockpit/blob/main/HACKING.md#updating-node_modules>`_.

View file

@ -110,7 +110,7 @@ $(SPEC): packaging/$(SPEC).in $(NODE_MODULES_TEST)
provides=$$(npm ls --omit dev --package-lock-only --depth=Infinity | grep -Eo '[^[:space:]]+@[^[:space:]]+' | sort -u | sed 's/^/Provides: bundled(npm(/; s/\(.*\)@/\1)) = /'); \
awk -v p="$$provides" '{gsub(/%{VERSION}/, "$(VERSION)"); gsub(/%{NPM_PROVIDES}/, p)}1' $< > $@
$(DIST_TEST): $(COCKPIT_REPO_STAMP) $(shell find src/ -type f) $(NODE_MODULES_TEST) package.json build.js
$(DIST_TEST): $(COCKPIT_REPO_STAMP) $(shell find src/ -type f) package.json build.js
NODE_ENV=production ./build.js
watch:
@ -171,6 +171,7 @@ EXTRA_DIST = dist src firefox-theme
COCKPIT_REPO_FILES = \
pkg/lib \
test/common \
tools/node-modules \
$(NULL)
COCKPIT_REPO_URL = https://github.com/cockpit-project/cockpit.git
@ -230,10 +231,11 @@ test/reference: test/common
update-reference-images: test/common test/reference
test/common/pixel-tests push
$(NODE_MODULES_TEST): package.json
rm -f package-lock.json # if it exists already, npm install won't update it; force that so that we always get up-to-date packages
env -u NODE_ENV npm install # unset NODE_ENV, skips devDependencies otherwise
env -u NODE_ENV npm prune
# We want tools/node-modules to run every time package-lock.json is requested
# See https://www.gnu.org/software/make/manual/html_node/Force-Targets.html
FORCE:
$(NODE_MODULES_TEST): FORCE tools/node-modules
tools/node-modules make_package_lock_json
.PHONY: test-compose
test-compose: bots

1
node_modules Submodule

@ -0,0 +1 @@
Subproject commit 4a571d49facafa6c3b154eb62128f98b88aff9eb