diff --git a/.github/ISSUE_TEMPLATE/add_monochrome_icon.yml b/.github/ISSUE_TEMPLATE/add_monochrome_icon.yml index ef0c57f1..4de24490 100644 --- a/.github/ISSUE_TEMPLATE/add_monochrome_icon.yml +++ b/.github/ISSUE_TEMPLATE/add_monochrome_icon.yml @@ -35,32 +35,49 @@ body: label: Categories multiple: true options: - - Animal - - Cloud + - AI + - Analytics-&-Monitoring + - Automation + - Browsers-&-Search + - Cloud-&-Hosting - Communication + - Community-&-Social + - Content-Management + - Crypto + - Databases - Design - Development + - Downloaders - E-Commerce - Education - - File + - File-Management-&-Sync - Finance - Food + - Framework - Gaming - Hardware - Health - - Location - - Logistics + - Home-Automation + - Identity + - Infrastructure + - Library + - Mapping-&-Location - Media - - Music + - Music-&-Audio - Nature + - Networking - News - - Organization - - Search + - Notes-&-Productivity + - Operating-Systems + - Organization-&-Planning + - Programming-Language - Security - - SocialMedia + - Software - Streaming - Travel + - Version-Control - Video + - Virtualization - type: input attributes: label: Aliases diff --git a/.github/ISSUE_TEMPLATE/add_normal_icon.yml b/.github/ISSUE_TEMPLATE/add_normal_icon.yml index af894568..b997f5ed 100644 --- a/.github/ISSUE_TEMPLATE/add_normal_icon.yml +++ b/.github/ISSUE_TEMPLATE/add_normal_icon.yml @@ -33,32 +33,49 @@ body: label: Categories multiple: true options: - - Animal - - Cloud + - AI + - Analytics-&-Monitoring + - Automation + - Browsers-&-Search + - Cloud-&-Hosting - Communication + - Community-&-Social + - Content-Management + - Crypto + - Databases - Design - Development + - Downloaders - E-Commerce - Education - - File + - File-Management-&-Sync - Finance - Food + - Framework - Gaming - Hardware - Health - - Location - - Logistics + - Home-Automation + - Identity + - Infrastructure + - Library + - Mapping-&-Location - Media - - Music + - Music-&-Audio - Nature + - Networking - News - - Organization - - Search + - Notes-&-Productivity + - Operating-Systems + - Organization-&-Planning + - Programming-Language - Security - - SocialMedia + - Software - Streaming - Travel + - Version-Control - Video + - Virtualization - type: input attributes: label: Aliases diff --git a/.github/ISSUE_TEMPLATE/update_monochrome_icon.yml b/.github/ISSUE_TEMPLATE/update_monochrome_icon.yml index 35a5010d..d00174b8 100644 --- a/.github/ISSUE_TEMPLATE/update_monochrome_icon.yml +++ b/.github/ISSUE_TEMPLATE/update_monochrome_icon.yml @@ -29,6 +29,54 @@ body: options: - SVG - PNG + - type: dropdown + attributes: + label: Categories + multiple: true + options: + - AI + - Analytics-&-Monitoring + - Automation + - Browsers-&-Search + - Cloud-&-Hosting + - Communication + - Community-&-Social + - Content-Management + - Crypto + - Databases + - Design + - Development + - Downloaders + - E-Commerce + - Education + - File-Management-&-Sync + - Finance + - Food + - Framework + - Gaming + - Hardware + - Health + - Home-Automation + - Identity + - Infrastructure + - Library + - Mapping-&-Location + - Media + - Music-&-Audio + - Nature + - Networking + - News + - Notes-&-Productivity + - Operating-Systems + - Organization-&-Planning + - Programming-Language + - Security + - Software + - Streaming + - Travel + - Version-Control + - Video + - Virtualization - type: textarea attributes: label: Additional information diff --git a/.github/ISSUE_TEMPLATE/update_normal_icon.yml b/.github/ISSUE_TEMPLATE/update_normal_icon.yml index 1087c87c..fe29c651 100644 --- a/.github/ISSUE_TEMPLATE/update_normal_icon.yml +++ b/.github/ISSUE_TEMPLATE/update_normal_icon.yml @@ -24,6 +24,54 @@ body: options: - SVG - PNG + - type: dropdown + attributes: + label: Categories + multiple: true + options: + - AI + - Analytics-&-Monitoring + - Automation + - Browsers-&-Search + - Cloud-&-Hosting + - Communication + - Community-&-Social + - Content-Management + - Crypto + - Databases + - Design + - Development + - Downloaders + - E-Commerce + - Education + - File-Management-&-Sync + - Finance + - Food + - Framework + - Gaming + - Hardware + - Health + - Home-Automation + - Identity + - Infrastructure + - Library + - Mapping-&-Location + - Media + - Music-&-Audio + - Nature + - Networking + - News + - Notes-&-Productivity + - Operating-Systems + - Organization-&-Planning + - Programming-Language + - Security + - Software + - Streaming + - Travel + - Version-Control + - Video + - Virtualization - type: textarea attributes: label: Additional information diff --git a/.github/workflows/on_icon_addition_approved.yml b/.github/workflows/on_icon_addition_approved.yml index 6801116b..244a5fe4 100644 --- a/.github/workflows/on_icon_addition_approved.yml +++ b/.github/workflows/on_icon_addition_approved.yml @@ -37,6 +37,58 @@ jobs: run: echo "ISSUE_FORM=$(python scripts/parse_issue_form.py)" >> "$GITHUB_OUTPUT" env: INPUT_ISSUE_BODY: ${{ github.event.issue.body }} + - name: Validate Categories + run: | + import json + import sys + import os + + # Load allowed categories from metadata.map.json + map_file = "metadata.map.json" + try: + with open(map_file, 'r', encoding='utf-8') as f: + map_data = json.load(f) + # Assuming the first key in the map holds the example structure + example_key = list(map_data.keys())[0] + allowed_categories = set(map_data[example_key]['categories']) + print(f"Loaded {len(allowed_categories)} allowed categories from {map_file}") + except Exception as e: + print(f"::error file={map_file}::Failed to load or parse allowed categories from {map_file}: {e}") + sys.exit(1) + + # Load submitted form data + form_json_string = os.environ.get('INPUT_ISSUE_FORM') + if not form_json_string: + print("::error::Failed to get form JSON from environment variable.") + sys.exit(1) + + try: + form_data = json.loads(form_json_string) + except json.JSONDecodeError as e: + print(f"::error::Failed to parse form JSON: {e}") + print(f"Form JSON string was: {form_json_string}") + sys.exit(1) + + # Extract submitted categories (handle potential missing key or None value) + submitted_categories_str = form_data.get('Categories') # Label from issue form + submitted_categories = set() + if submitted_categories_str: + submitted_categories = set(cat.strip() for cat in submitted_categories_str.split('\\n') if cat.strip()) + + print(f"Submitted categories: {submitted_categories or 'None'}") + + # Validate + invalid_categories = submitted_categories - allowed_categories + + if invalid_categories: + print(f"::error::Invalid categories found: {', '.join(sorted(list(invalid_categories)))}") + print("Please ensure all submitted categories exist in metadata.map.json.") + sys.exit(1) + else: + print("All submitted categories are valid.") + + env: + INPUT_ISSUE_FORM: ${{ steps.parse_issue_form.outputs.ISSUE_FORM }} - name: Create metadata file run: python scripts/generate_metadata_file.py ${{ env.ICON_TYPE }} addition env: diff --git a/.github/workflows/on_icon_update_approved.yml b/.github/workflows/on_icon_update_approved.yml index e87de189..cc2ca7fa 100644 --- a/.github/workflows/on_icon_update_approved.yml +++ b/.github/workflows/on_icon_update_approved.yml @@ -37,6 +37,62 @@ jobs: run: echo "ISSUE_FORM=$(python scripts/parse_issue_form.py)" >> "$GITHUB_OUTPUT" env: INPUT_ISSUE_BODY: ${{ github.event.issue.body }} + - name: Validate Categories + run: | + import json + import sys + import os + + # Load allowed categories from metadata.map.json + map_file = "metadata.map.json" + try: + with open(map_file, 'r', encoding='utf-8') as f: + map_data = json.load(f) + # Assuming the first key in the map holds the example structure + example_key = list(map_data.keys())[0] + allowed_categories = set(map_data[example_key]['categories']) + print(f"Loaded {len(allowed_categories)} allowed categories from {map_file}") + except Exception as e: + print(f"::error file={map_file}::Failed to load or parse allowed categories from {map_file}: {e}") + sys.exit(1) + + # Load submitted form data + form_json_string = os.environ.get('INPUT_ISSUE_FORM') + if not form_json_string: + print("::error::Failed to get form JSON from environment variable.") + sys.exit(1) + + try: + form_data = json.loads(form_json_string) + except json.JSONDecodeError as e: + print(f"::error::Failed to parse form JSON: {e}") + print(f"Form JSON string was: {form_json_string}") + sys.exit(1) + + # Extract submitted categories (handle potential missing key or None value) + # NOTE: The update forms might not have a 'Categories' field if categories aren't updatable via that form. + # If 'Categories' is missing or None in the form data, validation passes trivially. + submitted_categories_str = form_data.get('Categories') # Label from issue form + submitted_categories = set() + if submitted_categories_str: + submitted_categories = set(cat.strip() for cat in submitted_categories_str.split('\\n') if cat.strip()) + + if not submitted_categories_str: + print("No categories submitted in this form, skipping validation.") + else: + print(f"Submitted categories: {submitted_categories}") + # Validate + invalid_categories = submitted_categories - allowed_categories + + if invalid_categories: + print(f"::error::Invalid categories found: {', '.join(sorted(list(invalid_categories)))}") + print("Please ensure all submitted categories exist in metadata.map.json.") + sys.exit(1) + else: + print("All submitted categories are valid.") + + env: + INPUT_ISSUE_FORM: ${{ steps.parse_issue_form.outputs.ISSUE_FORM }} - name: Update metadata file run: python scripts/generate_metadata_file.py ${{ env.ICON_TYPE }} update env: diff --git a/metadata.map.json b/metadata.map.json new file mode 100644 index 00000000..68287b6e --- /dev/null +++ b/metadata.map.json @@ -0,0 +1,65 @@ +{ + "example-icon": { + "base": "svg", + "aliases": [ + "example-alias", + "another-alias" + ], + "categories": [ + "AI", + "Analytics-&-Monitoring", + "Automation", + "Browsers-&-Search", + "Cloud-&-Hosting", + "Communication", + "Community-&-Social", + "Content-Management", + "Crypto", + "Databases", + "Design", + "Development", + "Downloaders", + "E-Commerce", + "Education", + "File-Management-&-Sync", + "Finance", + "Food", + "Framework", + "Gaming", + "Hardware", + "Health", + "Home-Automation", + "Identity", + "Infrastructure", + "Library", + "Mapping-&-Location", + "Media", + "Music-&-Audio", + "Nature", + "Networking", + "News", + "Notes-&-Productivity", + "Operating-Systems", + "Organization-&-Planning", + "Programming-Language", + "Security", + "Software", + "Streaming", + "Travel", + "Version-Control", + "Video", + "Virtualization" + ], + "update": { + "timestamp": "YYYY-MM-DDTHH:mm:ssZ", + "author": { + "id": 12345678, + "login": "contributor-login" + } + }, + "colors": { + "dark": "example-icon-dark", + "light": "example-icon-light" + } + } +} \ No newline at end of file