Skip to content

Commit 30f5211

Browse files
authored
Merge branch 'ServiceNowDevProgram:main' into main
2 parents 21b615f + 111a9d9 commit 30f5211

File tree

3,044 files changed

+45497
-5910
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

3,044 files changed

+45497
-5910
lines changed

.github/pull_request_template.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# PR Description:
2+
replace this with your description
3+
4+
# Pull Request Checklist
5+
6+
## Overview
7+
- [x] Put an x inside of the square brackets to check each item.
8+
- [ ] I have read and understood the [CONTRIBUTING.md](CONTRIBUTING.md) guidelines
9+
- [ ] My pull request has a descriptive title that accurately reflects the changes and the description has been filled in above.
10+
- [ ] I've included only files relevant to the changes described in the PR title and description
11+
- [ ] I've created a new branch in my forked repository for this contribution
12+
13+
## Code Quality
14+
- [ ] My code is relevant to ServiceNow developers
15+
- [ ] My code snippets expand meaningfully on official ServiceNow documentation (if applicable)
16+
- [ ] I've disclosed use of ES2021 features (if applicable)
17+
- [ ] I've tested my code snippets in a ServiceNow environment (where possible)
18+
19+
## Repository Structure Compliance
20+
- [ ] I've placed my code snippet(s) in one of the required top-level categories:
21+
- `Core ServiceNow APIs/`
22+
- `Server-Side Components/`
23+
- `Client-Side Components/`
24+
- `Modern Development/`
25+
- `Integration/`
26+
- `Specialized Areas/`
27+
- [ ] I've used appropriate sub-categories within the top-level categories
28+
- [ ] Each code snippet has its own folder with a descriptive name
29+
30+
## Documentation
31+
- [ ] I've included a README.md file for each code snippet
32+
- [ ] The README.md includes:
33+
- Description of the code snippet functionality
34+
- Usage instructions or examples
35+
- Any prerequisites or dependencies
36+
- (Optional) Screenshots or diagrams if helpful
37+
38+
## Restrictions
39+
- [ ] My PR does not include XML exports of ServiceNow records
40+
- [ ] My PR does not contain sensitive information (passwords, API keys, tokens)
41+
- [ ] My PR does not include changes that fall outside the described scope
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#!/usr/bin/env node
2+
3+
const { execSync } = require('child_process');
4+
5+
const allowedCategories = new Set([
6+
'Core ServiceNow APIs',
7+
'Server-Side Components',
8+
'Client-Side Components',
9+
'Modern Development',
10+
'Integration',
11+
'Specialized Areas'
12+
]);
13+
14+
function resolveDiffRange() {
15+
if (process.argv[2]) {
16+
return process.argv[2];
17+
}
18+
19+
const inCI = process.env.GITHUB_ACTIONS === 'true';
20+
if (!inCI) {
21+
return 'origin/main...HEAD';
22+
}
23+
24+
const base = process.env.GITHUB_BASE_REF ? `origin/${process.env.GITHUB_BASE_REF}` : 'origin/main';
25+
const head = process.env.GITHUB_SHA || 'HEAD';
26+
return `${base}...${head}`;
27+
}
28+
29+
function getChangedFiles(diffRange) {
30+
let output;
31+
try {
32+
output = execSync(`git diff --name-only --diff-filter=ACMR ${diffRange}`, {
33+
encoding: 'utf8',
34+
stdio: ['ignore', 'pipe', 'pipe']
35+
});
36+
} catch (error) {
37+
console.error('Failed to collect changed files. Ensure the base branch is fetched.');
38+
console.error(error.stderr?.toString() || error.message);
39+
process.exit(1);
40+
}
41+
42+
return output
43+
.split('\n')
44+
.map((line) => line.trim())
45+
.filter(Boolean);
46+
}
47+
48+
function validateFilePath(filePath) {
49+
const normalized = filePath.replace(/\\/g, '/');
50+
const segments = normalized.split('/');
51+
52+
// Check for invalid characters that break local file systems
53+
for (let i = 0; i < segments.length; i++) {
54+
const segment = segments[i];
55+
56+
// Check for trailing periods (invalid on Windows)
57+
if (segment.endsWith('.')) {
58+
return `Invalid folder/file name '${segment}' in path '${normalized}': Names cannot end with a period (.) as this breaks local file system sync on Windows.`;
59+
}
60+
61+
// Check for trailing spaces (invalid on Windows)
62+
if (segment.endsWith(' ')) {
63+
return `Invalid folder/file name '${segment}' in path '${normalized}': Names cannot end with a space as this breaks local file system sync on Windows.`;
64+
}
65+
66+
// Check for reserved Windows names
67+
const reservedNames = ['CON', 'PRN', 'AUX', 'NUL', 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9', 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9'];
68+
const nameWithoutExt = segment.split('.')[0].toUpperCase();
69+
if (reservedNames.includes(nameWithoutExt)) {
70+
return `Invalid folder/file name '${segment}' in path '${normalized}': '${nameWithoutExt}' is a reserved name on Windows and will break local file system sync.`;
71+
}
72+
73+
// Check for invalid characters (Windows and general file system restrictions)
74+
const invalidChars = /[<>:"|?*\x00-\x1F]/;
75+
if (invalidChars.test(segment)) {
76+
return `Invalid folder/file name '${segment}' in path '${normalized}': Contains characters that are invalid on Windows file systems (< > : " | ? * or control characters).`;
77+
}
78+
}
79+
80+
if (!allowedCategories.has(segments[0])) {
81+
return null;
82+
}
83+
84+
// Files must live under: Category/Subcategory/SpecificUseCase/<file>
85+
if (segments.length < 4) {
86+
return `Move '${normalized}' under a valid folder hierarchy (Category/Subcategory/Use-Case/your-file). Files directly inside '${segments[0]}' or its subcategories are not allowed.`;
87+
}
88+
89+
return null;
90+
}
91+
92+
function main() {
93+
const diffRange = resolveDiffRange();
94+
const changedFiles = getChangedFiles(diffRange);
95+
96+
if (changedFiles.length === 0) {
97+
console.log('No relevant file changes detected.');
98+
return;
99+
}
100+
101+
const problems = [];
102+
103+
for (const filePath of changedFiles) {
104+
const issue = validateFilePath(filePath);
105+
if (issue) {
106+
problems.push(issue);
107+
}
108+
}
109+
110+
if (problems.length > 0) {
111+
console.error('Folder structure violations found:');
112+
for (const msg of problems) {
113+
console.error(` - ${msg}`);
114+
}
115+
process.exit(1);
116+
}
117+
118+
console.log('Folder structure looks good.');
119+
}
120+
121+
main();

.github/workflows/pages.yml

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# GitHub Pages deployment workflow
2+
name: Deploy GitHub Pages
3+
4+
on:
5+
workflow_dispatch:
6+
7+
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
8+
permissions:
9+
contents: read
10+
pages: write
11+
id-token: write
12+
13+
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
14+
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
15+
concurrency:
16+
group: pages-${{ github.ref }}
17+
cancel-in-progress: true
18+
19+
jobs:
20+
# Build and optimize job
21+
build:
22+
runs-on: ubuntu-latest
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v4
26+
27+
- name: Setup Node.js
28+
uses: actions/setup-node@v4
29+
with:
30+
node-version: '18'
31+
cache: 'npm'
32+
33+
- name: Install build dependencies
34+
run: |
35+
npm init -y
36+
npm install --save-dev html-minifier-terser clean-css-cli terser html-validate
37+
38+
- name: Validate HTML files
39+
run: |
40+
echo "Validating HTML files..."
41+
npx html-validate *.html pages/*.html || echo "HTML validation completed with warnings"
42+
43+
- name: Optimize assets
44+
run: |
45+
echo "Optimizing HTML files..."
46+
# Create backup directory
47+
mkdir -p .backup
48+
49+
# Minify HTML files (preserve original structure)
50+
find . -name "*.html" -not -path "./node_modules/*" -not -path "./.backup/*" | while read file; do
51+
echo "Minifying: $file"
52+
npx html-minifier-terser \
53+
--collapse-whitespace \
54+
--remove-comments \
55+
--remove-optional-tags \
56+
--remove-redundant-attributes \
57+
--remove-script-type-attributes \
58+
--remove-style-link-type-attributes \
59+
--minify-css \
60+
--minify-js \
61+
"$file" -o "$file.tmp" && mv "$file.tmp" "$file"
62+
done
63+
64+
# Minify CSS files if any exist
65+
if find . -name "*.css" -not -path "./node_modules/*" -not -path "./.backup/*" | grep -q .; then
66+
echo "Optimizing CSS files..."
67+
find . -name "*.css" -not -path "./node_modules/*" -not -path "./.backup/*" | while read file; do
68+
echo "Minifying: $file"
69+
npx cleancss "$file" -o "$file"
70+
done
71+
fi
72+
73+
# Remove build dependencies from final artifact
74+
rm -rf node_modules package*.json
75+
76+
- name: Setup Pages
77+
id: pages
78+
uses: actions/configure-pages@v4
79+
80+
- name: Upload artifact
81+
uses: actions/upload-pages-artifact@v3
82+
with:
83+
path: '.'
84+
85+
# Deployment job
86+
deploy:
87+
environment:
88+
name: github-pages
89+
url: ${{ steps.deployment.outputs.page_url }}
90+
runs-on: ubuntu-latest
91+
needs: build
92+
steps:
93+
- name: Deploy to GitHub Pages
94+
id: deployment
95+
uses: actions/deploy-pages@v4

0 commit comments

Comments
 (0)