Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/check-branch-name.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Validate Branch Name

on:
pull_request:
types: [ opened, synchronize, reopened ]

jobs:
check-branch-name:
runs-on: ubuntu-latest
steps:
- name: Check branch name format
run: |
BRANCH_NAME="${{ github.head_ref }}"
echo "Checking branch name: $BRANCH_NAME"
if [[ ! "$BRANCH_NAME" =~ ^(chore|feature|fix|hotfix|patch|refactor)/[a-z0-9._-]+$ ]]; then
echo "❌ Invalid branch name: $BRANCH_NAME"
echo "✅ Should match: feature/foo-bar, hotfix/issue-123, etc."
exit 1
fi
10 changes: 10 additions & 0 deletions .github/workflows/check-commit-message.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: Check Commit Messages

on: [pull_request]

jobs:
lint-commits:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: wagoid/commitlint-github-action@v5
26 changes: 26 additions & 0 deletions .gitmessage.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Conventional Commit template
# Lines starting with # are ignored by Git.
# Keep header ≤72 chars; subject in imperative mood.
# Examples of <type>: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert

<type>(<scope>): <subject>

# Why?
# - What problem does this change solve?
# - Why now / context?

# What changed?
# - Key changes, trade-offs, alternatives considered
# - Any user-facing behavior changes

# How was it tested?
# - Test strategy, manual steps, screenshots if relevant

# Notes
# - Known limitations, follow-ups, migrations

# Footer (one per line)
# BREAKING CHANGE: <describe the breaking change and migration path>
# Closes #123
# Relates-to #456
# Co-authored-by: Name <email>
1 change: 1 addition & 0 deletions .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
npx commitlint --edit "$1"
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20.19.4
13 changes: 8 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ ARG XDEBUG_VERSION="xdebug-3.3.2"
ENV COMPOSER_ALLOW_SUPERUSER=1
ENV GITHUB_OAUTH_TOKEN=$GITHUB_OAUTH_TOKEN
ENV PHP_DIR /usr/local/etc/php
ARG YARN_VERSION="1.22.22"
ARG NVM_VERSION="v0.40.3"
ARG NODE_VERSION="20.19.4"

ARG NVM_VERSION="v0.39.7"
ARG NODE_VERSION="18.20.2"
# base packages
RUN apt-get update
RUN apt-get install -y \
Expand All @@ -33,16 +34,18 @@ RUN apt-get install -y \
libmagickwand-dev


# nvm

# nvm + node + yarn via corepack
ENV NVM_DIR=/root/.nvm
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/$NVM_VERSION/install.sh | bash
# Install Node, enable Corepack (Yarn)
RUN bash -lc "source $NVM_DIR/nvm.sh && nvm install $NODE_VERSION && corepack enable && corepack prepare yarn@stable --activate"

RUN bash -lc "source $NVM_DIR/nvm.sh && nvm install $NODE_VERSION && corepack enable && corepack prepare yarn@$YARN_VERSION --activate"
RUN apt clean && rm -rf /var/lib/apt/lists/*

# Set up our PATH correctly so we don't have to long-reference npm, node, &c.
ENV NODE_PATH=$NVM_DIR/versions/node/v$NODE_VERSION/lib/node_modules
ENV PATH=$NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH

ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/

RUN install-php-extensions bcmath exif gettext gd imagick mbstring openssl pcntl pdo pdo_mysql sockets ${XDEBUG_VERSION} zip apcu redis igbinary
Expand Down
76 changes: 76 additions & 0 deletions commitlint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
const WIP_REGEX = /^wip[:]?$/i;
const RULE_ERROR_LEVEL = 2;
const HEADER_MAX_LENGTH = 100;
const SUBJECT_MIN_LENGTH = 5;

module.exports = {
extends: ["@commitlint/config-conventional"],
rules: {
"custom-subject-empty": [RULE_ERROR_LEVEL, "never"],
"custom-type-enum": [RULE_ERROR_LEVEL, "always"],
"custom-no-wip": [RULE_ERROR_LEVEL, "always"],
"custom-no-wip-subject": [RULE_ERROR_LEVEL, "always"],
"subject-min-length": [RULE_ERROR_LEVEL, "always", SUBJECT_MIN_LENGTH],
"subject-case": [0], // optional: allow flexibility in subject case
"header-max-length": [RULE_ERROR_LEVEL, "always", HEADER_MAX_LENGTH]
},
plugins: [
{
rules: {
"custom-subject-empty": ({ subject }) =>
subject && subject.trim().length > 0
? [true]
: [
false,
"The commit needs a description after the colon (:). Eg: feat: add new feature"
],
"custom-type-enum": ({ type }) => {
const allowedTypes = [
"feat",
"fix",
"hotfix",
"docs",
"style",
"refactor",
"test",
"chore"
];

if (!type) {
return [
false,
"Missing type. Use: feat, fix, chore, refactor, etc."
];
}

if (!allowedTypes.includes(type)) {
return [
false,
`Type "${type} is invalid". Allowed types: ${allowedTypes.join(
", "
)}`
];
}

return [true];
},
"custom-no-wip": ({ header }) => {
const isWipOnly = WIP_REGEX.test(header.trim());
return [
!isWipOnly,
"Commit message cannot be just \"WIP\" (use a descriptive message)."
];
},
"custom-no-wip-subject": ({ subject }) => {
if (!subject) return [true];

const isWipOnly = WIP_REGEX.test(subject.trim());
return [
!isWipOnly,
"Subject cannot be just \"WIP\". Use a descriptive message like \"implement user login\" instead."
];
}
}
}
]
};
26 changes: 26 additions & 0 deletions gitmessage.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Conventional Commit template
# Lines starting with # are ignored by Git.
# Keep header ≤72 chars; subject in imperative mood.
# Examples of <type>: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert

<type>(<scope>): <subject>

# Why?
# - What problem does this change solve?
# - Why now / context?

# What changed?
# - Key changes, trade-offs, alternatives considered
# - Any user-facing behavior changes

# How was it tested?
# - Test strategy, manual steps, screenshots if relevant

# Notes
# - Known limitations, follow-ups, migrations

# Footer (one per line)
# BREAKING CHANGE: <describe the breaking change and migration path>
# Closes #123
# Relates-to #456
# Co-authored-by: Name <email>
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
"private": true,
"scripts": {
"prod": "gulp --production",
"dev": "gulp watch"
"dev": "gulp watch",
"prepare": "husky",
"postinstall":"git config --local commit.template .gitmessage.txt || true"
},
"devDependencies": {
"gulp": "^3.9.1",
"laravel-elixir": "^5.0.0",
"bootstrap-sass": "^3.3.0"
}
"@commitlint/config-conventional": "^19.8.1",
"husky": "^9.0.11"
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}
80 changes: 80 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


"@commitlint/config-conventional@^19.8.1":
version "19.8.1"
resolved "https://registry.yarnpkg.com/@commitlint/config-conventional/-/config-conventional-19.8.1.tgz#eab42df58cda44f18410ae0cbd6785ece00f214b"
integrity sha512-/AZHJL6F6B/G959CsMAzrPKKZjeEiAVifRyEwXxcT6qtqbPwGw+iQxmNS+Bu+i09OCtdNRW6pNpBvgPrtMr9EQ==
dependencies:
"@commitlint/types" "^19.8.1"
conventional-changelog-conventionalcommits "^7.0.2"

"@commitlint/types@^19.8.1":
version "19.8.1"
resolved "https://registry.yarnpkg.com/@commitlint/types/-/types-19.8.1.tgz#7971fbd56b0cfb31692a4e1941b74ac8217c44e5"
integrity sha512-/yCrWGCoA1SVKOks25EGadP9Pnj0oAIHGpl2wH2M2Y46dPM2ueb8wyCVOD7O3WCTkaJ0IkKvzhl1JY7+uCT2Dw==
dependencies:
"@types/conventional-commits-parser" "^5.0.0"
chalk "^5.3.0"

"@types/conventional-commits-parser@^5.0.0":
version "5.0.1"
resolved "https://registry.yarnpkg.com/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.1.tgz#8cb81cf170853496cbc501a3b32dcf5e46ffb61a"
integrity sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==
dependencies:
"@types/node" "*"

"@types/node@*":
version "24.5.2"
resolved "https://registry.yarnpkg.com/@types/node/-/node-24.5.2.tgz#52ceb83f50fe0fcfdfbd2a9fab6db2e9e7ef6446"
integrity sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==
dependencies:
undici-types "~7.12.0"

array-ify@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece"
integrity sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==

chalk@^5.3.0:
version "5.6.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.6.2.tgz#b1238b6e23ea337af71c7f8a295db5af0c158aea"
integrity sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==

compare-func@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-2.0.0.tgz#fb65e75edbddfd2e568554e8b5b05fff7a51fcb3"
integrity sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==
dependencies:
array-ify "^1.0.0"
dot-prop "^5.1.0"

conventional-changelog-conventionalcommits@^7.0.2:
version "7.0.2"
resolved "https://registry.yarnpkg.com/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-7.0.2.tgz#aa5da0f1b2543094889e8cf7616ebe1a8f5c70d5"
integrity sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==
dependencies:
compare-func "^2.0.0"

dot-prop@^5.1.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88"
integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==
dependencies:
is-obj "^2.0.0"

husky@^9.0.11:
version "9.1.7"
resolved "https://registry.yarnpkg.com/husky/-/husky-9.1.7.tgz#d46a38035d101b46a70456a850ff4201344c0b2d"
integrity sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==

is-obj@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982"
integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==

undici-types@~7.12.0:
version "7.12.0"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.12.0.tgz#15c5c7475c2a3ba30659529f5cdb4674b622fafb"
integrity sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==