Skip to content

Commit 50c820a

Browse files
committed
refactor: convert pack bundle & publish to scripts
Move the inline pack publishing and bundling logic from the release-codeql workflow into dedicated scripts: - scripts/publish-packs.sh: Publishes all CodeQL packs to GHCR with pre-release detection, token validation, and dry-run support. - scripts/bundle-packs.sh: Bundles all CodeQL packs into .tar.gz archives with configurable output directory and dry-run support.
1 parent 6000046 commit 50c820a

File tree

3 files changed

+472
-63
lines changed

3 files changed

+472
-63
lines changed

.github/workflows/release-codeql.yml

Lines changed: 3 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,6 @@ jobs:
4343
release_name: ${{ steps.version.outputs.release_name }}
4444
version: ${{ steps.version.outputs.version }}
4545

46-
env:
47-
PUBLISHABLE_PACKS_LIST: |
48-
javascript/frameworks/cap/src
49-
javascript/frameworks/cap/ext
50-
javascript/frameworks/cap/lib
51-
javascript/frameworks/ui5/src
52-
javascript/frameworks/ui5/ext
53-
javascript/frameworks/ui5/lib
54-
javascript/frameworks/xsjs/src
55-
javascript/frameworks/xsjs/ext
56-
javascript/frameworks/xsjs/lib
57-
javascript/heuristic-models/ext
58-
5946
steps:
6047
- name: CodeQL - Validate and parse version
6148
id: version
@@ -91,9 +78,7 @@ jobs:
9178
9279
- name: CodeQL - Install pack dependencies
9380
shell: bash
94-
run: |
95-
chmod +x ./scripts/install-packs.sh
96-
./scripts/install-packs.sh
81+
run: ./scripts/install-packs.sh
9782

9883
- name: CodeQL - Validate version consistency
9984
run: |
@@ -106,59 +91,14 @@ jobs:
10691
if: inputs.publish_codeql_packs
10792
env:
10893
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
109-
run: |
110-
RELEASE_NAME="${{ steps.version.outputs.release_name }}"
111-
112-
# Read the shared pack list from the job-level environment variable.
113-
mapfile -t PUBLISHABLE_PACKS <<< "${PUBLISHABLE_PACKS_LIST}"
114-
115-
# Prerelease versions (containing a hyphen) require --allow-prerelease
116-
PRERELEASE_FLAG=""
117-
if [[ "${RELEASE_NAME}" == *-* ]]; then
118-
PRERELEASE_FLAG="--allow-prerelease"
119-
echo "Detected prerelease version — using ${PRERELEASE_FLAG}"
120-
fi
121-
122-
echo "Publishing CodeQL packs..."
123-
for pack_dir in "${PUBLISHABLE_PACKS[@]}"; do
124-
if [ -d "${pack_dir}" ]; then
125-
pack_name=$(grep -m1 "^name:" "${pack_dir}/qlpack.yml" | awk '{print $2}')
126-
echo "📦 Publishing ${pack_name} from ${pack_dir}..."
127-
codeql pack publish --threads=-1 ${PRERELEASE_FLAG} -- "${pack_dir}"
128-
echo "✅ Published ${pack_name}"
129-
else
130-
echo "⚠️ Skipping: ${pack_dir} not found"
131-
fi
132-
done
94+
run: ./scripts/publish-packs.sh "${{ steps.version.outputs.release_name }}"
13395

13496
- name: CodeQL - Skip pack publishing
13597
if: '!inputs.publish_codeql_packs'
13698
run: echo "⏭️ CodeQL pack publishing disabled via workflow input"
13799

138100
- name: CodeQL - Bundle CodeQL packs
139-
run: |
140-
mkdir -p dist-packs
141-
142-
# Bundle all publishable packs
143-
# Read the pack list from the environment into a Bash array.
144-
# Each line in PUBLISHABLE_PACKS_LIST becomes one element.
145-
mapfile -t PUBLISHABLE_PACKS <<< "${PUBLISHABLE_PACKS_LIST}"
146-
147-
echo "Bundling CodeQL packs..."
148-
for pack_dir in "${PUBLISHABLE_PACKS[@]}"; do
149-
if [ -d "${pack_dir}" ]; then
150-
pack_name=$(grep -m1 "^name:" "${pack_dir}/qlpack.yml" | awk '{print $2}')
151-
# Convert pack name to filename: advanced-security/foo -> foo
152-
bundle_name="${pack_name#advanced-security/}"
153-
output="dist-packs/${bundle_name}.tar.gz"
154-
echo "📦 Bundling ${pack_name} -> ${output}..."
155-
codeql pack bundle --threads=-1 --output="${output}" -- "${pack_dir}"
156-
echo "✅ Bundled ${bundle_name}"
157-
fi
158-
done
159-
echo ""
160-
echo "Bundled packs:"
161-
ls -lh dist-packs/
101+
run: ./scripts/bundle-packs.sh --output-dir dist-packs
162102

163103
- name: CodeQL - Upload pack artifacts
164104
uses: actions/upload-artifact@v6

scripts/bundle-packs.sh

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
## bundle-packs.sh
5+
## Bundle CodeQL packs into distributable .tar.gz archives.
6+
##
7+
## This script bundles all publishable CodeQL packs in the codeql-sap-js
8+
## repository using `codeql pack bundle`, producing .tar.gz files suitable
9+
## for upload as release artifacts or offline distribution.
10+
##
11+
## Requirements:
12+
## - The `codeql` CLI must be available on PATH.
13+
##
14+
## Usage:
15+
## ./scripts/bundle-packs.sh [OPTIONS]
16+
## ./scripts/bundle-packs.sh --output-dir dist-packs
17+
## ./scripts/bundle-packs.sh --dry-run
18+
##
19+
## Options:
20+
## --output-dir <dir> Directory for bundled .tar.gz files (default: dist-packs).
21+
## --dry-run Show what would be bundled without actually bundling.
22+
## -h, --help Show this help message.
23+
24+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
25+
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
26+
27+
DRY_RUN=false
28+
OUTPUT_DIR="dist-packs"
29+
30+
## All publishable pack directories relative to repo root.
31+
## These must match the packs listed in publish-packs.sh.
32+
PUBLISHABLE_PACKS=(
33+
"javascript/frameworks/cap/src"
34+
"javascript/frameworks/cap/ext"
35+
"javascript/frameworks/cap/lib"
36+
"javascript/frameworks/ui5/src"
37+
"javascript/frameworks/ui5/ext"
38+
"javascript/frameworks/ui5/lib"
39+
"javascript/frameworks/xsjs/src"
40+
"javascript/frameworks/xsjs/ext"
41+
"javascript/frameworks/xsjs/lib"
42+
"javascript/heuristic-models/ext"
43+
)
44+
45+
usage() {
46+
cat <<EOF
47+
Usage: $0 [OPTIONS]
48+
49+
Bundle CodeQL packs into distributable .tar.gz archives.
50+
51+
OPTIONS:
52+
--output-dir <dir> Directory for bundled .tar.gz files (default: dist-packs).
53+
--dry-run Show what would be bundled without actually bundling.
54+
-h, --help Show this help message.
55+
56+
EXAMPLES:
57+
./scripts/bundle-packs.sh
58+
./scripts/bundle-packs.sh --output-dir dist-packs
59+
./scripts/bundle-packs.sh --dry-run
60+
EOF
61+
}
62+
63+
while [[ $# -gt 0 ]]; do
64+
case $1 in
65+
--output-dir)
66+
if [[ $# -lt 2 || "${2-}" == -* ]]; then
67+
echo "Error: --output-dir requires a value" >&2
68+
usage >&2
69+
exit 1
70+
fi
71+
OUTPUT_DIR="$2"
72+
shift 2
73+
;;
74+
--dry-run)
75+
DRY_RUN=true
76+
shift
77+
;;
78+
-h|--help)
79+
usage
80+
exit 0
81+
;;
82+
*)
83+
echo "Error: Unknown option $1" >&2
84+
usage >&2
85+
exit 1
86+
;;
87+
esac
88+
done
89+
90+
## ── Diagnostics ──────────────────────────────────────────────────────────────
91+
92+
echo "╔══════════════════════════════════════════════════════════════╗"
93+
echo "║ CodeQL Pack Bundler ║"
94+
echo "╚══════════════════════════════════════════════════════════════╝"
95+
echo ""
96+
echo "Output dir: ${OUTPUT_DIR}"
97+
echo "Dry run: ${DRY_RUN}"
98+
echo "Repo root: ${REPO_ROOT}"
99+
echo ""
100+
101+
# Verify codeql is available
102+
if ! command -v codeql &> /dev/null; then
103+
echo "Error: 'codeql' CLI not found on PATH." >&2
104+
echo "Install CodeQL CLI and ensure it is on your PATH before running this script." >&2
105+
exit 1
106+
fi
107+
108+
echo "CodeQL CLI: $(command -v codeql)"
109+
echo "CodeQL version: $(codeql version --format=terse)"
110+
echo ""
111+
112+
## ── Bundle packs ─────────────────────────────────────────────────────────────
113+
114+
cd "${REPO_ROOT}"
115+
116+
if [[ "${DRY_RUN}" == false ]]; then
117+
mkdir -p "${OUTPUT_DIR}"
118+
fi
119+
120+
BUNDLED=0
121+
SKIPPED=0
122+
FAILED=0
123+
124+
echo "Bundling ${#PUBLISHABLE_PACKS[@]} CodeQL packs..."
125+
echo ""
126+
127+
for pack_dir in "${PUBLISHABLE_PACKS[@]}"; do
128+
if [[ ! -d "${pack_dir}" ]]; then
129+
echo "⚠️ Skipping: ${pack_dir} (directory not found)"
130+
SKIPPED=$((SKIPPED + 1))
131+
continue
132+
fi
133+
134+
if [[ ! -f "${pack_dir}/qlpack.yml" ]]; then
135+
echo "⚠️ Skipping: ${pack_dir} (no qlpack.yml found)"
136+
SKIPPED=$((SKIPPED + 1))
137+
continue
138+
fi
139+
140+
pack_name=$(grep -m1 "^name:" "${pack_dir}/qlpack.yml" | awk '{print $2}')
141+
# Convert pack name to filename: advanced-security/foo -> foo
142+
bundle_name="${pack_name#advanced-security/}"
143+
output="${OUTPUT_DIR}/${bundle_name}.tar.gz"
144+
145+
echo "────────────────────────────────────────────────────────────────"
146+
echo "📦 Pack: ${pack_name}"
147+
echo " Directory: ${pack_dir}"
148+
echo " Output: ${output}"
149+
150+
if [[ "${DRY_RUN}" == true ]]; then
151+
echo " Action: [DRY RUN] Would bundle with: codeql pack bundle --threads=-1 --output=${output} -- ${pack_dir}"
152+
BUNDLED=$((BUNDLED + 1))
153+
continue
154+
fi
155+
156+
if codeql pack bundle --threads=-1 --output="${output}" -- "${pack_dir}"; then
157+
echo " ✅ Bundled ${bundle_name}"
158+
BUNDLED=$((BUNDLED + 1))
159+
else
160+
EXIT_CODE=$?
161+
echo " ❌ Failed to bundle ${bundle_name} (exit code: ${EXIT_CODE})" >&2
162+
FAILED=$((FAILED + 1))
163+
fi
164+
echo ""
165+
done
166+
167+
## ── Summary ──────────────────────────────────────────────────────────────────
168+
169+
echo ""
170+
echo "════════════════════════════════════════════════════════════════"
171+
echo "Summary"
172+
echo "════════════════════════════════════════════════════════════════"
173+
echo " Total: ${#PUBLISHABLE_PACKS[@]}"
174+
echo " Bundled: ${BUNDLED}"
175+
echo " Skipped: ${SKIPPED}"
176+
echo " Failed: ${FAILED}"
177+
echo ""
178+
179+
if [[ "${DRY_RUN}" == false && -d "${OUTPUT_DIR}" ]]; then
180+
echo "Bundled packs:"
181+
ls -lh "${OUTPUT_DIR}/"
182+
echo ""
183+
fi
184+
185+
if [[ "${FAILED}" -gt 0 ]]; then
186+
echo "${FAILED} pack(s) failed to bundle." >&2
187+
exit 1
188+
fi
189+
190+
if [[ "${DRY_RUN}" == true ]]; then
191+
echo "✅ Dry run complete. No packs were actually bundled."
192+
else
193+
echo "✅ All CodeQL packs bundled successfully."
194+
fi

0 commit comments

Comments
 (0)