Skip to content

Commit

Permalink
ci: enforce usage of scopes in PR title (#3672)
Browse files Browse the repository at this point in the history
* feat: semantic PR configuration generator script

* ci: stricter semantic PR title

generated

* ci: lint and test typescript files

* chore: use exisitng mod id in PR template
  • Loading branch information
scarf005 authored Nov 28, 2023
1 parent a300d8e commit 660cef0
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 2 deletions.
4 changes: 2 additions & 2 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ If you use GitHub's web editor to edit files, you shouldn't need to do this as t
PR TITLE: Please follow Conventional Commits: https://www.conventionalcommits.org
This makes it clear at a glance what the PR is about.
For example:
feat(content, mods): new item for <mod name>
feat(content, mods/DinoMod): new dinosaur species
For more info on which categories are available, see: https://docs.cataclysmbn.org/en/contribute/changelog_guidelines/
If the PR is a port or adaptation of DDA content, please indicate it by adding "port" in PR title, like:
feat(port): <feature name> from DDA
Expand Down Expand Up @@ -74,4 +74,4 @@ If this is a PR that modifies build process or code organization:
If this is a PR that removes JSON entities:
- [ ] The removed JSON entities have new entries in `data/json/obsoletion/` folder or use some other migration process for existing saves.
-->
-->
87 changes: 87 additions & 0 deletions .github/semantic.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,90 @@
# This file is generated by `scripts/semantic.ts`, do not edit manually.
#
# For more on configuration:
# https://github.com/Ezard/semantic-prs?tab=readme-ov-file#configuration-options
#
# Validate the PR title, and ignore all commit messages
enabled: true
titleOnly: true
targetUrl: 'https://docs.cataclysmbn.org/en/contribute/changelog_guidelines/'
types:
- feat
- fix
- docs
- style
- refactor
- perf
- test
- build
- ci
- chore
- revert
scopes:
- content
- UI
- i18n
- balance
- port
- mods/DinoMod
- mods/FujiStruct
- mods/Graphical_Overmap
- mods/Graphical_Overmap_Fujistruct
- mods/Graphical_Overmap_More_Locations
- mods/Graphical_Overmap_Urban_Development
- mods/MMA
- mods/Mundane_Zombies
- mods/No_Acid_Zombies
- mods/No_Anthills
- mods/No_Bees
- mods/No_Big_Zombies
- mods/No_Blobs
- mods/No_Explosive_Zombies
- mods/No_Ferals
- mods/No_Fungi
- mods/No_Rail_Stations
- mods/Old_Mutations
- mods/Only_Wildlife
- mods/RL_Classes
- mods/StatsThroughSkills
- mods/UDP_BN_FAKE_SNOW
- mods/Urban_Development
- mods/Zombie_Nightvision
- mods/aftershock
- mods/alt_map_key
- mods/cbm_slots
- mods/classic_zombies
- mods/craftgp
- mods/crazy_cataclysm
- mods/crt_expansion
- mods/desertpack
- mods/disable_lifting
- mods/elevated_bridges
- mods/fuji_mpp
- mods/generic_guns
- mods/limit_fungal_growth
- mods/magiclysm
- mods/manualbionicinstall
- mods/modular_turrets
- mods/more_classes_scenarios
- mods/my_sweet_cataclysm
- mods/no_filthy_clothing
- mods/no_flaming_weapons
- mods/no_hope
- mods/no_medieval_items
- mods/no_mutagen
- mods/no_npc_food
- mods/no_olg_guns
- mods/no_religious_Texts
- mods/no_reviving_zombies
- mods/no_rivtech_guns
- mods/no_scifi
- mods/no_survivor_armor
- mods/novitamins
- mods/ruralbiome
- mods/saveload_lua_test
- mods/sees_player_hitbutton
- mods/sees_player_retro
- mods/smart_house_remote_mod
- mods/speedydex
- mods/stats_through_kills
- mods/test_data
4 changes: 4 additions & 0 deletions .github/workflows/autofix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,7 @@ jobs:
If you don't do this, your following work will be based on the old commit, and cause MERGE CONFLICT.
- name: lint and test typescript files
run: |
deno lint
deno test
84 changes: 84 additions & 0 deletions scripts/semantic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* Generates allowed semantic PR title schema for project.
*
* 1. collects list of all mod IDs
* 2. generate list of allowed scopes using mod IDs
* 3. write to `.github/semantic.yaml` file
*/
import type { Config } from "https://raw.githubusercontent.com/Ezard/semantic-prs/d6970fded0b5bcb1a2d55778e5be94a83453a897/functions/src/config.ts"
import mod from "https://raw.githubusercontent.com/commitizen/conventional-commit-types/c3a9be4c73e47f2e8197de775f41d981701407fb/index.json" with {
type: "json",
}
import { walk } from "$std/fs/walk.ts"
import { asynciter } from "$asynciter/mod.ts"
import { SafeParseSuccess, z } from "$zod/mod.ts"
import * as YAML from "$std/yaml/stringify.ts"
import type {} from "$ts-reset/entrypoints/filter-boolean.d.ts"
import { outdent } from "$outdent/mod.ts"

type Modinfo = z.infer<typeof modinfoSchema>

/** Extracts ID from Modinfo entry. */
export const modinfoSchema = z
.object({ type: z.literal("MOD_INFO"), id: z.string() })
.transform((x) => x.id)

const parseModinfos = (xs: unknown[]) => xs.map((x) => modinfoSchema.safeParse(x))

/**
* @param path Path to `modinfo.json` file.
* @returns Mod ID or `undefined` if file is invalid.
*/
export const extractModinfo = (path: string): Promise<string | undefined> =>
Deno
.readTextFile(path)
.then(JSON.parse)
.then(parseModinfos)
.then((xs) => xs.find((x): x is SafeParseSuccess<Modinfo> => x.success)?.data)

/** List of all mod IDs. */
export const allModIds = await asynciter(walk("data/mods", {
maxDepth: 2,
includeDirs: false,
exts: [".json"],
match: [/modinfo\.json/],
skip: [/bn/],
}))
.map(({ path }) => path)
.concurrentUnorderedMap(extractModinfo)
.collect()
.then((xs) => xs.filter(Boolean))

/**
* see `changelog_guidelines.md` for list of all allowed scopes.
*/
export const scopes = {
/** Default allowed scopes */
base: ["content", "UI", "i18n", "balance", "port"],
/** List of `mods/<MOD_ID>` */
mods: allModIds.toSorted().map((x) => `mods/${x}`),
}

// https://github.com/Ezard/semantic-prs?tab=readme-ov-file#configuration
const config = {
enabled: true,
titleOnly: true,
targetUrl: "https://docs.cataclysmbn.org/en/contribute/changelog_guidelines/",

types: Object.keys(mod.types),
scopes: Object.values(scopes).flat(),
} satisfies Partial<Config>

if (import.meta.main) {
const setting = YAML.stringify(config)
const content = outdent`
# This file is generated by \`scripts/semantic.ts\`, do not edit manually.
#
# For more on configuration:
# https://github.com/Ezard/semantic-prs?tab=readme-ov-file#configuration-options
#
# Validate the PR title, and ignore all commit messages
${setting}
`
await Deno.writeTextFile(".github/semantic.yml", content)
}

0 comments on commit 660cef0

Please sign in to comment.