Skip to content

Commit 5a7e187

Browse files
committed
Update to work with voc4cat-tool 1.0.0 (v1.0 formats)
1 parent 1d7114f commit 5a7e187

18 files changed

Lines changed: 443 additions & 149 deletions

File tree

.github/workflows/ci-pr.yml

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,25 @@ on:
77
# forks. Since the workflow only accesses the xlsx and turtle files, but does
88
# not run any code, it is safe to use pull_request_target. More info:
99
# https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/
10+
# zizmor: ignore[dangerous-triggers] OK as per comment above
1011
pull_request_target:
1112
branches:
1213
- main
1314
types: [opened, reopened, synchronize]
1415
workflow_dispatch:
1516

1617
env:
17-
FORCE_COLOR: "1" # Make tool output pretty.
1818
PIP_DISABLE_PIP_VERSION_CHECK: "1"
1919
PIP_PROGRESS_BAR: "off"
2020
LOGLEVEL: "DEBUG"
2121
RUN_URL: $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID
2222

23+
concurrency:
24+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
25+
cancel-in-progress: true
26+
27+
permissions: {}
28+
2329
jobs:
2430
build_vocab:
2531
name: Merge & build vocabulary
@@ -29,31 +35,33 @@ jobs:
2935
timeout-minutes: 10
3036

3137
permissions:
32-
# Give the default GITHUB_TOKEN write permission to commit to the PR branch.
33-
contents: write
38+
contents: write # Give the default GITHUB_TOKEN write permission to commit to the PR branch.
3439

3540
steps:
3641
- name: Checkout PR branch into cwd
37-
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
42+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
3843
with:
3944
# Checkout the fork/head-repository to push changes to the fork.
4045
# Without this the base repository will be checked out and committed to.
4146
repository: ${{ github.event.pull_request.head.repo.full_name }}
42-
4347
# Checkout the branch made in the fork.
4448
ref: ${{ github.head_ref }}
49+
# Be specific about keeping credentials (it is the default)
50+
persist-credentials: true
4551

4652
- name: Checkout main branch into directory _main_branch/
47-
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
53+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
4854
with:
4955
ref: main
5056
path: _main_branch
5157
# This sparse-checkout includes all toplevel files and everything below vocabularies/
5258
sparse-checkout: |
5359
vocabularies/
5460
fetch-depth: 1
61+
# Be specific about keeping credentials (it is the default)
62+
persist-credentials: true
5563

56-
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c
64+
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548
5765
with:
5866
python-version: '3.13'
5967

@@ -62,19 +70,16 @@ jobs:
6270
python -VV
6371
python -m pip install --upgrade pip setuptools wheel
6472
65-
# install tagged version
66-
python -m pip install git+https://github.com/nfdi4cat/voc4cat-tool.git@v0.10.0
67-
# python -m pip install git+https://github.com/nfdi4cat/voc4cat-tool.git@main
73+
# Select to install a stable tagged version or main branch (in development)
74+
# python -m pip install git+https://github.com/nfdi4cat/voc4cat-tool.git@v1.0.0
75+
python -m pip install git+https://github.com/nfdi4cat/voc4cat-tool.git@main
6876
6977
# install custom pylode 2.x (adds sorted collections,
7078
# uses URIs as fragment IDs and is git-installable)
7179
python -m pip install git+https://github.com/dalito/pyLODE.git@nfdi4cat-2.x
7280
73-
# Example for installing from private repo:
74-
# python -m pip install git+https://anon:${{ SECRETS.READ_PAT_VOC4CAT }}@github.com/dalito/voc4cat-tool.git@main
75-
7681
- name: Set dynamic environment variables.
77-
run: |
82+
run: | # zizmor: ignore[github-env] safe without user controllable input
7883
echo "RUN_DATE=$(date +'%Y-%m-%dT%H%M')" >> $GITHUB_ENV
7984
8085
- name: Run voc4cat (pre-convert checks)
@@ -91,34 +96,37 @@ jobs:
9196
voc4cat convert --config _main_branch/idranges.toml --logfile outbox/voc4cat.log --outdir outbox inbox-excel-vocabs/
9297
if [ ! -f outbox/*.ttl ]; then
9398
echo "No ttl file in outbox. Building joined vocabulary ttl-file from individual ttl-files in vocabulary."
94-
voc4cat transform --join --logfile outbox/voc4cat.log --outdir outbox/ vocabularies/
99+
voc4cat transform --join --config _main_branch/idranges.toml --logfile outbox/voc4cat.log --outdir outbox/ vocabularies/
95100
fi
96101
97102
- name: Run voc4cat (post-convert checks)
98103
run: |
99104
# check all ttl file(s) in outbox
100-
voc4cat check --config _main_branch/idranges.toml --logfile outbox/voc4cat.log outbox/
105+
voc4cat check --redundant-hierarchies --config _main_branch/idranges.toml --logfile outbox/voc4cat.log outbox/
101106
# check if vocabulary changes are allowed
102107
voc4cat check --config _main_branch/idranges.toml --logfile outbox/voc4cat.log --ci-post _main_branch/vocabularies outbox/
103108
104109
- name: Run voc4cat (build HTML documentation)
105110
run: |
106111
voc4cat docs --logfile outbox/voc4cat.log --force outbox/
107112
108-
- name: Split vocabulary and merge into vocabulary dir (in PR branch)
113+
- name: Split vocabulary, merge into vocabulary dir (in PR branch) and update provenance info
109114
run: |
110-
voc4cat transform --split --inplace --logfile outbox/voc4cat.log --outdir outbox_new_voc outbox/
115+
voc4cat transform --split --inplace --config idranges.toml --logfile outbox/voc4cat.log --outdir outbox_new_voc outbox/
111116
voc4cat-merge --logfile outbox/voc4cat.log outbox_new_voc/ vocabularies/
112117
# copy xlsx to outbox so that the xlsx file is part of the artifact
113118
find inbox-excel-vocabs -name '*.xlsx' -exec cp {} -t outbox/ \;
114119
git status
120+
# Add/update dct:created and dct:modified base on git history
121+
voc4cat transform --prov-from-git --inplace --config idranges.toml --logfile outbox/voc4cat.log vocabularies/
115122
116123
- name: Run voc4cat (re-build updated Excel file and joined turtle vocabulary file)
117124
# Passing the config is important to make use of the prefixes therein.
118125
run: |
119126
mkdir -p outbox/updated-xlsx-ttl
120-
voc4cat convert --config idranges.toml --logfile outbox/voc4cat.log --template templates/voc4cat_template_043.xlsx outbox/updated-xlsx-ttl
121-
voc4cat transform --config idranges.toml --logfile outbox/voc4cat.log -O outbox/updated-xlsx-ttl --join vocabularies/
127+
voc4cat transform --join --config idranges.toml --logfile outbox/voc4cat.log --outdir outbox/updated-xlsx-ttl vocabularies/
128+
# Using a template is optional and gives just a warning if missing.
129+
voc4cat convert --config idranges.toml --logfile outbox/voc4cat.log --template templates/default_sheets.xlsx outbox/updated-xlsx-ttl
122130
123131
- name: Store artifacts
124132
if: ${{ always() }}

.github/workflows/merge.yml

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,33 +21,41 @@ on:
2121
workflow_dispatch:
2222

2323
env:
24-
FORCE_COLOR: "1" # Make tool output pretty.
2524
PIP_DISABLE_PIP_VERSION_CHECK: "1"
2625
PIP_PROGRESS_BAR: "off"
2726
LOGLEVEL: "DEBUG"
2827

28+
concurrency:
29+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
30+
cancel-in-progress: true
31+
32+
permissions: {}
33+
2934
jobs:
3035
build:
3136
name: Development build of vocabulary & documentation
3237
permissions:
33-
# Required for peaceiris/actions-gh-pages below
34-
contents: write
38+
contents: write # Required for peaceiris/actions-gh-pages below
3539
runs-on: ubuntu-latest
3640
timeout-minutes: 10
3741
steps:
38-
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
42+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
3943
with:
4044
# Using fetch-depth 0 is the only way to get all tags which are needed for building docs.
4145
fetch-depth: 0
46+
# Be specific about keeping credentials (it is the default)
47+
persist-credentials: true
4248

4349
- name: Checkout gh-pages branch to dir publish/
44-
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
50+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
4551
with:
4652
ref: gh-pages
4753
path: publish
4854
fetch-depth: 1
55+
# Be specific about keeping credentials (it is the default)
56+
persist-credentials: true
4957

50-
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c
58+
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548
5159
with:
5260
python-version: '3.13'
5361

@@ -56,9 +64,9 @@ jobs:
5664
python -VV
5765
python -m pip install --upgrade pip setuptools wheel
5866
59-
# install tagged version
60-
python -m pip install git+https://github.com/nfdi4cat/voc4cat-tool.git@v0.10.0
61-
# python -m pip install git+https://github.com/nfdi4cat/voc4cat-tool.git@main
67+
# Select to install a stable tagged version or main branch (in development)
68+
# python -m pip install git+https://github.com/nfdi4cat/voc4cat-tool.git@v1.0.0
69+
python -m pip install git+https://github.com/nfdi4cat/voc4cat-tool.git@main
6270
6371
# install custom pylode 2.x
6472
python -m pip install git+https://github.com/dalito/pyLODE.git@nfdi4cat-2.x
@@ -77,7 +85,7 @@ jobs:
7785
find publish/dev/ -type f \( -name "*.xlsx" -o -name "*.ttl" \) -delete
7886
cp -r vocabularies/. publish/dev/
7987
# Build joined turtle
80-
voc4cat transform --logfile publish/dev/voc4cat.log --join publish/dev/
88+
voc4cat transform --join --config idranges.toml --logfile publish/dev/voc4cat.log publish/dev/
8189
8290
- name: Run voc4cat (build pyLODE HTML documentation)
8391
run: |
@@ -88,7 +96,8 @@ jobs:
8896
- name: Run voc4cat (build current Excel file)
8997
# Passing the config is important to make use of the prefixes therein.
9098
run: |
91-
voc4cat convert --config idranges.toml --logfile publish/dev/voc4cat.log --template templates/voc4cat_template_043.xlsx publish/dev/
99+
# Using a template is optional and gives just a warning if missing.
100+
voc4cat convert --config idranges.toml --logfile publish/dev/voc4cat.log --template templates/default_sheets.xlsx publish/dev/
92101
93102
- name: Deploy updated gh-pages content
94103
# This replaces all prior content in gh-pages branch. But we have

.github/workflows/pr-checks.yml

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# This workflow checks for common PR submission issues and provides helpful feedback
2+
# - PRs from fork's main branch (helpful workflow suggestion)
3+
# - Organization account submissions (critical - blocks CI due to GitHub limitation)
4+
#
5+
# Security Note: This workflow uses pull_request_target which runs in the context
6+
# of the base repository, not the fork. User-controlled data (PR titles, descriptions,
7+
# branch names, usernames) must be sanitized before use to prevent script injection.
8+
9+
name: PR Submission Checks
10+
11+
on:
12+
pull_request_target:
13+
types: [opened, reopened, synchronize]
14+
branches:
15+
- main
16+
17+
permissions: {}
18+
19+
concurrency:
20+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
21+
cancel-in-progress: true
22+
23+
jobs:
24+
check-pr-submission:
25+
name: Check PR submission best practices
26+
runs-on: ubuntu-latest
27+
permissions:
28+
contents: read
29+
pull-requests: write # to post a message to PR
30+
31+
steps:
32+
- name: Check if PR is from main branch of fork
33+
id: check-main-branch
34+
uses: actions/github-script@v8
35+
with:
36+
script: |
37+
const pr = context.payload.pull_request;
38+
39+
// Get PR details from context (these are all user-controlled)
40+
const headRef = pr.head.ref;
41+
const headRepo = pr.head.repo.full_name;
42+
const baseRepo = pr.base.repo.full_name;
43+
const isFork = headRepo !== baseRepo;
44+
const isFromMain = headRef === 'main';
45+
const isFromOrg = pr.head.repo.owner.type === 'Organization';
46+
const headOwnerLogin = pr.head.repo.owner.login;
47+
const baseOwnerLogin = pr.base.repo.owner.login;
48+
49+
// Log details - no user input in template literals for security
50+
console.log('PR number:', pr.number);
51+
console.log('Head branch:', headRef);
52+
console.log('Head repo:', headRepo);
53+
console.log('Base repo:', baseRepo);
54+
console.log('Is fork:', isFork);
55+
console.log('From main branch:', isFromMain);
56+
console.log('Owner type:', pr.head.repo.owner.type);
57+
console.log('Head owner login:', headOwnerLogin);
58+
console.log('Base owner login:', baseOwnerLogin);
59+
60+
core.setOutput('is_fork', isFork);
61+
core.setOutput('is_from_main', isFromMain);
62+
core.setOutput('is_from_org', isFromOrg);
63+
core.setOutput('head_ref', headRef);
64+
core.setOutput('head_repo', headRepo);
65+
core.setOutput('head_owner_login', headOwnerLogin);
66+
core.setOutput('base_owner_login', baseOwnerLogin);
67+
68+
return {
69+
isFork,
70+
isFromMain,
71+
isFromOrg,
72+
needsComment: isFork && isFromMain
73+
};
74+
75+
- name: Post comment about main branch submission
76+
if: steps.check-main-branch.outputs.is_fork == 'true' && steps.check-main-branch.outputs.is_from_main == 'true'
77+
uses: actions/github-script@v8
78+
with:
79+
script: |
80+
const pr = context.payload.pull_request;
81+
82+
// Check if we already posted this comment
83+
const comments = await github.rest.issues.listComments({
84+
owner: context.repo.owner,
85+
repo: context.repo.repo,
86+
issue_number: pr.number
87+
});
88+
89+
const botComment = comments.data.find(comment =>
90+
comment.user.type === 'Bot' &&
91+
comment.body.includes('submitted from the main branch')
92+
);
93+
94+
if (botComment) {
95+
console.log('Comment about main branch already exists, skipping');
96+
return;
97+
}
98+
99+
// Sanitize username - GitHub usernames can only contain alphanumeric characters and hyphens
100+
const username = pr.user.login.replace(/[^a-zA-Z0-9-]/g, '');
101+
102+
// Post helpful comment
103+
const commentBody = `Hi @${username}! 👋
104+
105+
Thank you for your contribution to voc4cat!
106+
107+
> [!WARNING]
108+
> We noticed that this pull request was submitted from the \`main\` branch of your fork.
109+
> While this works, it can cause issues:
110+
111+
- It makes it harder to keep your fork updated with upstream changes
112+
- You won't be able to work on multiple PRs at once
113+
- Future contributions may be complicated by merge conflicts
114+
115+
This PR can still be merged, but please use feature branches going forward!
116+
117+
For more information, see our [How to contribute](https://nfdi4cat.github.io/voc4cat/docs_usage/how-to-contribute.html) guide.
118+
119+
*If you have any questions, please don't hesitate to ask!* 🚀`;
120+
121+
await github.rest.issues.createComment({
122+
owner: context.repo.owner,
123+
repo: context.repo.repo,
124+
issue_number: pr.number,
125+
body: commentBody
126+
});
127+
128+
- name: Post info about organization account
129+
if: steps.check-main-branch.outputs.is_from_org == 'true' && steps.check-main-branch.outputs.is_fork == 'true' && steps.check-main-branch.outputs.head_owner_login != steps.check-main-branch.outputs.base_owner_login
130+
uses: actions/github-script@v8
131+
with:
132+
script: |
133+
const pr = context.payload.pull_request;
134+
135+
// Check if we already posted this comment
136+
const comments = await github.rest.issues.listComments({
137+
owner: context.repo.owner,
138+
repo: context.repo.repo,
139+
issue_number: pr.number
140+
});
141+
142+
const botComment = comments.data.find(comment =>
143+
comment.user.type === 'Bot' &&
144+
comment.body.includes('organization account')
145+
);
146+
147+
if (botComment) {
148+
console.log('Comment about organization account already exists, skipping');
149+
return;
150+
}
151+
152+
// Sanitize username - GitHub usernames can only contain alphanumeric characters and hyphens
153+
const username = pr.user.login.replace(/[^a-zA-Z0-9-]/g, '');
154+
155+
const commentBody = `Hi @${username}! 👋
156+
157+
> [!CAUTION]
158+
> We noticed that this pull request comes from a fork under an organization account,
159+
> which will prevent our CI workflow from working correctly.
160+
161+
GitHub does not allow the "Allow edits from maintainers" option for forks in organizations (see [discussion](https://github.com/orgs/community/discussions/5634)).
162+
Our CI needs this permission to commit turtle files and clean up Excel files.
163+
164+
**This PR cannot be merged as-is.** Please:
165+
1. Fork voc4cat to your personal GitHub account
166+
2. Create a feature branch with your changes
167+
3. Submit a new PR from your personal fork
168+
4. Close this PR
169+
170+
Sorry for the inconvenience - this is a GitHub limitation, not our choice!`;
171+
172+
await github.rest.issues.createComment({
173+
owner: context.repo.owner,
174+
repo: context.repo.repo,
175+
issue_number: pr.number,
176+
body: commentBody
177+
});
178+

0 commit comments

Comments
 (0)