Compare commits

..

38 commits
v0.2.1 ... main

Author SHA1 Message Date
Gitea Actions
a992d1cfd9 chore(release): [skip ci] 2025-04-09 17:49:25 +00:00
c142133a34
Merge pull request 'Prepare for next release' (#13) from main into release
All checks were successful
Release / Release (push) Successful in 57s
Reviewed-on: #13
2025-04-09 17:48:31 +00:00
653e80ee73
ci: add test job to CI configuration (#12)
All checks were successful
Lint Pull Request / Lint PR Title (pull_request) Has been skipped
Go CI / test (pull_request) Successful in 8s
Go CI / lint (pull_request) Successful in 10s
Reviewed-on: #12
Co-authored-by: Jan Klattenhoff <jan@kjan.email>
Co-committed-by: Jan Klattenhoff <jan@kjan.email>
2025-04-09 17:46:26 +00:00
e332ef87cb
feat: add linters (#11)
Reviewed-on: #11
Co-authored-by: Jan Klattenhoff <jan@kjan.email>
Co-committed-by: Jan Klattenhoff <jan@kjan.email>
2025-04-09 17:40:45 +00:00
1b86948c60
ci: add Go CI workflow configuration file
Some checks failed
Lint Pull Request / Lint PR Title (pull_request) Successful in 27s
Go CI / lint (pull_request) Failing after 35s
2025-04-09 19:28:15 +02:00
667ccdd9a1
Merge pull request 'Prepare for next release' (#9) from main into release
All checks were successful
Release / Release (push) Successful in 55s
Reviewed-on: #9
2025-04-09 16:51:59 +00:00
66f0f05e55
ci: update release workflow for error handling
All checks were successful
Lint Pull Request / Lint PR Title (pull_request) Has been skipped
2025-04-09 18:51:21 +02:00
9a125449d5
Merge pull request 'Prepare for next release' (#8) from main into release
Some checks failed
Release / Release (push) Failing after 50s
Reviewed-on: #8
2025-04-09 16:46:29 +00:00
c420551cdb
chore: Configure Renovate (#4)
All checks were successful
Lint Pull Request / Lint PR Title (pull_request) Has been skipped
Welcome to [Renovate](https://github.com/renovatebot/renovate)! This is an onboarding PR to help you understand and configure settings before regular Pull Requests begin.

🚦 To activate Renovate, merge this Pull Request. To disable Renovate, simply close this Pull Request unmerged.

---
### Detected Package Files

 * `.gitea/workflows/pr.yml` (github-actions)
 * `.gitea/workflows/release.yml` (github-actions)
 * `.gitea/workflows/test.yml` (github-actions)
 * `go.mod` (gomod)

### Configuration Summary

Based on the default config's presets, Renovate will:

  - Start dependency updates only once this onboarding PR is merged
  - Enable Renovate Dependency Dashboard creation.
  - Use semantic commit type `fix` for dependencies and `chore` for all others if semantic commits are in use.
  - Ignore `node_modules`, `bower_components`, `vendor` and various test/tests (except for nuget) directories.
  - Group known monorepo packages together.
  - Use curated list of recommended non-monorepo package groupings.
  - Apply crowd-sourced package replacement rules.
  - Apply crowd-sourced workarounds for known problems with packages.
  - Preserve (but continue to upgrade) any existing SemVer ranges.
  - Enable Renovate Dependency Dashboard creation.
  - Rebase existing PRs any time the base branch has been updated.
  - Use semantic prefixes for commit messages and PR titles.
  - Raise PR when vulnerability alerts are detected with label `'security'`.
  - Group all `minor` and `patch` updates together.
  - Keep existing branches updated even when not scheduled.
  - Show all Merge Confidence badges for pull requests.

🔡 Do you want to change how Renovate upgrades your dependencies? Add your custom config to `renovate.json` in this branch. Renovate will update the Pull Request description the next time it runs.

---

### What to Expect

With your current configuration, Renovate will create 2 Pull Requests:

<details>
<summary>chore(deps): update dependency go to 1.24</summary>

  - Schedule: ["at any time"]
  - Branch name: `renovate/all-minor-patch`
  - Merge into: `main`
  - Upgrade [go](https://github.com/actions/go-versions) to `1.24`

</details>

<details>
<summary>chore(deps): update actions/setup-go action to v5</summary>

  - Schedule: ["at any time"]
  - Branch name: `renovate/actions-setup-go-5.x`
  - Merge into: `main`
  - Upgrade [actions/setup-go](https://github.com/actions/setup-go) to `v5`

</details>

---

 Got questions? Check out Renovate's [Docs](https://docs.renovatebot.com/), particularly the Getting Started section.
If you need any further assistance then you can also [request help here](https://github.com/renovatebot/renovate/discussions).

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).

<!--renovate-config-hash:0a0b8841b14278c0c061ba4db2615c8f351f5dda327a6ee5707d6e1ee5980f1c-->

Co-authored-by: Jan K9f <jan@kjan.email>
Reviewed-on: #4
Co-authored-by: Renovate Bot <renovate@kjan.de>
Co-committed-by: Renovate Bot <renovate@kjan.de>
2025-04-09 16:44:40 +00:00
7e2de542b6
docs: update README with usage and validation rules (#7)
Reviewed-on: #7
Co-authored-by: Jan Klattenhoff <jan@kjan.email>
Co-committed-by: Jan Klattenhoff <jan@kjan.email>
2025-04-09 16:43:32 +00:00
08b43cc51b
refactor(validation): simplify regex and error messages 2025-04-09 18:37:58 +02:00
Gitea Actions
372ed39a62 chore(release): [skip ci] 2025-04-09 16:32:02 +00:00
041db18447
Merge pull request 'refactor: some polishing' (#6) from main into release
All checks were successful
Release / Release (push) Successful in 1m32s
Reviewed-on: #6
2025-04-09 16:30:34 +00:00
86febd99e5
refactor: some polishing
All checks were successful
Lint Pull Request / Lint PR Title (pull_request) Has been skipped
BREAKING CHANGE: Version 1
2025-04-09 18:29:31 +02:00
Gitea Actions
befdff3be1 chore(release): [skip ci] 2025-04-09 16:26:10 +00:00
e26143661c
Merge pull request 'feat: initial implementation' (#5) from main into release
All checks were successful
Release / Release (push) Successful in 56s
Reviewed-on: #5
2025-04-09 16:25:18 +00:00
64260f301a
ci: add condition to skip linting on release branches
All checks were successful
Lint Pull Request / Lint Pr Title (pull_request) Has been skipped
2025-04-09 18:24:53 +02:00
9b1a6a928e
fix(validation): update error message for invalid commit format
All checks were successful
Lint Pull Request / Lint Pr Title (pull_request) Successful in 9s
2025-04-09 18:22:37 +02:00
c84b1ecd26
fix(main): improve error message for invalid PR title
All checks were successful
Lint Pull Request / Lint Pr Title (pull_request) Successful in 9s
2025-04-09 18:20:59 +02:00
8981c8367e
fix(main): improve error message for invalid PR title
Some checks failed
Lint Pull Request / Lint Pr Title (pull_request) Failing after 9s
2025-04-09 18:20:34 +02:00
19b376ac40
refactor: clean up unused dependencies and functions
Some checks failed
Lint Pull Request / Lint Pr Title (pull_request) Failing after 9s
2025-04-09 18:19:21 +02:00
044823552b
feat: add GitHub event handling and pull request title display
All checks were successful
Lint Pull Request / Lint Pr Title (pull_request) Successful in 9s
2025-04-09 18:17:12 +02:00
2c943b845f
ci: add step to read event.json in PR workflow
All checks were successful
Lint Pull Request / Lint Pr Title (pull_request) Successful in 9s
2025-04-09 18:15:52 +02:00
ce06de60eb
ci: update pull request types for linting workflow
All checks were successful
Lint Pull Request / Lint Pr Title (pull_request) Successful in 9s
2025-04-09 18:13:59 +02:00
80ab70da04
chore: remove invoke-binary.js and update main.go logic
All checks were successful
Lint Pull Request / Lint Pr Title (pull_request) Successful in 9s
2025-04-09 18:11:23 +02:00
6d9c48078c
feat(action): update to use Go for pull request linting
All checks were successful
Lint Pull Request / Lint Pr Title (pull_request) Successful in 9s
2025-04-09 18:10:18 +02:00
da4a8b3030
feat(invoke-binary): add ls command execution in runGo function
Some checks failed
Lint Pull Request / Lint Pr Title (pull_request) Failing after 4s
2025-04-09 18:08:58 +02:00
72b5dd18f3
build(workflows): update CI configuration and remove test file
Some checks failed
Lint Pull Request / Lint Pr Title (pull_request) Failing after 4s
2025-04-09 18:07:13 +02:00
7ded9bab13
ci: update container configuration in PR workflow
Some checks failed
Test Go Action / use-go-action (push) Failing after 10s
Lint Pull Request / Lint Pr Title (pull_request) Failing after 24s
2025-04-09 18:02:26 +02:00
3253d5ac63
ci: update PR workflow to use golang image
Some checks failed
Test Go Action / use-go-action (push) Failing after 7s
Lint Pull Request / Lint Pr Title (pull_request) Failing after 13s
2025-04-09 18:01:43 +02:00
142ef2e8f8
ci: add always condition to lint action steps
Some checks failed
Test Go Action / use-go-action (push) Failing after 4s
Lint Pull Request / Lint Pr Title (pull_request) Failing after 9s
2025-04-09 17:53:47 +02:00
50c451f69e
ci: update action directory path in workflow config
Some checks failed
Test Go Action / use-go-action (push) Failing after 4s
Lint Pull Request / Lint Pr Title (pull_request) Failing after 4s
2025-04-09 17:51:05 +02:00
c9fd83e531
ci: add debugging steps and permission settings to CI
Some checks failed
Test Go Action / use-go-action (push) Failing after 4s
Lint Pull Request / Lint Pr Title (pull_request) Failing after 4s
2025-04-09 17:47:32 +02:00
5fd5b36be7
ci: add test workflow for Go Action
Some checks failed
Test Go Action / use-go-action (push) Failing after 16s
Lint Pull Request / Lint Pr Title (pull_request) Failing after 19s
2025-04-09 17:39:19 +02:00
6c118fb9ff
build: add Go installation step in PR workflow
Some checks failed
Lint Pull Request / Lint Pr Title (pull_request) Failing after 8s
2025-04-09 17:20:20 +02:00
aa1601e751
ci: add pull request linting workflow configuration
Some checks failed
Lint Pull Request / Lint Pr Title (pull_request) Failing after 28s
2025-04-09 17:17:55 +02:00
09380fb8d0
feat: add pull request linting action and validation logic 2025-04-09 17:16:18 +02:00
Gitea Actions
d0e7c0bec7 chore(release): [skip ci] 2025-04-09 14:59:03 +00:00
12 changed files with 287 additions and 4 deletions

29
.gitea/workflows/CI.yml Normal file
View file

@ -0,0 +1,29 @@
name: "Go CI"
on:
pull_request:
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: 1.24.2
- name: golangci-lint
uses: golangci/golangci-lint-action@v7
with:
version: v2.0
test:
name: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: 1.24.2
- name: Test
run: go test ./...

21
.gitea/workflows/pr.yml Normal file
View file

@ -0,0 +1,21 @@
name: "Lint Pull Request"
on:
pull_request:
types: [opened, edited, reopened, synchronize]
jobs:
lint:
name: Lint PR Title
runs-on: ubuntu-latest
if: github.base_ref != 'release'
steps:
- name: Install go
uses: actions/setup-go@v5
with:
go-version: 1.24.2
- name: Run Pull Request Lint Action
uses: https://git.kjan.de/actions/pull-request-lint@main

View file

@ -52,23 +52,25 @@ jobs:
run: | run: |
git add docs/ git add docs/
git commit -m "chore(release): [skip ci]" git commit -m "chore(release): [skip ci]"
continue-on-error: true
- name: Push changes to release branch - name: Push changes to release branch
if: ${{ steps.semantic.outputs.new_release_published }} if: ${{ steps.semantic.outputs.new_release_published }}
run: | run: |
git remote set-url origin git@${{ env.GITEA_DOMAIN }}:${{ github.repository }}.git git remote set-url origin git@${{ env.GITEA_DOMAIN }}:${{ github.repository }}.git
git push origin HEAD:${{ env.RELEASE_BRANCH }} git push origin HEAD:${{ env.RELEASE_BRANCH }}
continue-on-error: true
- name: Checkout target branch - name: Checkout target branch
if: ${{ steps.semantic.outputs.new_release_published && !(env.SKIP_MERGE == true) }} if: ${{ !(env.SKIP_MERGE == true) }}
run: git reset --hard && git checkout ${{ env.TARGET_BRANCH }} && git pull run: git reset --hard && git checkout ${{ env.TARGET_BRANCH }} && git pull
- name: Merge release - name: Merge release
if: ${{ steps.semantic.outputs.new_release_published && !(env.SKIP_MERGE == true) }} if: ${{ !(env.SKIP_MERGE == true) }}
run: git merge ${{ env.RELEASE_BRANCH }} run: git merge ${{ env.RELEASE_BRANCH }}
- name: Push changes to target branch - name: Push changes to target branch
if: ${{ steps.semantic.outputs.new_release_published && !(env.SKIP_MERGE == true) }} if: ${{ !(env.SKIP_MERGE == true) }}
run: | run: |
git remote set-url origin git@${{ env.GITEA_DOMAIN }}:${{ github.repository }}.git git remote set-url origin git@${{ env.GITEA_DOMAIN }}:${{ github.repository }}.git
git push origin HEAD:${{ env.TARGET_BRANCH }} git push origin HEAD:${{ env.TARGET_BRANCH }}

4
.golangci.yml Normal file
View file

@ -0,0 +1,4 @@
version: "2"
linters:
enable:
- revive

View file

@ -1,3 +1,41 @@
# pull-request-lint # pull-request-lint
Lints the title of a pull request A GitHub/Gitea Action that lints pull request titles to ensure they follow the [Conventional Commits](https://www.conventionalcommits.org/) format.
## Usage
Add the following to your GitHub/Gitea workflow:
```yaml
name: Pull Request Lint
on:
pull_request:
types: [opened, edited, reopened, synchronize]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install go
uses: actions/setup-go@v5
with:
go-version: 1.24.2
- uses: https://git.kjan.de/actions/pull-request-lint@release
```
## Validation Rules
The action enforces the following Conventional Commits rules for PR titles:
- Format must be: `type(scope)!: description` (scope and breaking change marker `!` are optional)
- Type and scope must be lowercase
- Description must start with lowercase
- Breaking change indicator and footer are mutually exclusive
- Body must be separated from description by a blank line
- Footer tokens must use hyphens instead of spaces (except for "BREAKING CHANGE")
## License
See [LICENSE](LICENSE) file for details.

5
action.yml Normal file
View file

@ -0,0 +1,5 @@
name: 'Pull Request Lint'
description: 'A gitea action to validate if a pr follows the semantic commit guidelines'
runs:
using: 'go'
main: 'main.go'

View file

@ -1,3 +1,46 @@
# [1.1.0](https://git.kjan.de/actions/pull-request-lint/compare/v1.0.0...v1.1.0) (2025-04-09)
### Features
* add linters ([#11](https://git.kjan.de/actions/pull-request-lint/issues/11)) ([e332ef8](https://git.kjan.de/actions/pull-request-lint/commit/e332ef87cbab6a7e0ebde5bd17a37b50c9aea967))
# [1.0.0](https://git.kjan.de/actions/pull-request-lint/compare/v0.3.0...v1.0.0) (2025-04-09)
### Code Refactoring
* some polishing ([86febd9](https://git.kjan.de/actions/pull-request-lint/commit/86febd99e507d250adb18fdfede0a01f6e6f8d46))
### BREAKING CHANGES
* Version 1
# [0.3.0](https://git.kjan.de/actions/pull-request-lint/compare/v0.2.1...v0.3.0) (2025-04-09)
### Bug Fixes
* **main:** improve error message for invalid PR title ([c84b1ec](https://git.kjan.de/actions/pull-request-lint/commit/c84b1ecd26d7cbd4530fed79e6078ced5d222e18))
* **main:** improve error message for invalid PR title ([8981c83](https://git.kjan.de/actions/pull-request-lint/commit/8981c8367edc7beff7a477510ba3a3a98b6e6751))
* **validation:** update error message for invalid commit format ([9b1a6a9](https://git.kjan.de/actions/pull-request-lint/commit/9b1a6a928e3483fd4ea6579cdcd8c8a9e95bb669))
### Features
* **action:** update to use Go for pull request linting ([6d9c480](https://git.kjan.de/actions/pull-request-lint/commit/6d9c48078c912b91bb60d8147b1b2d7e74ad8643))
* add GitHub event handling and pull request title display ([0448235](https://git.kjan.de/actions/pull-request-lint/commit/044823552b5fecf0b076098d1bc47d213c00f604))
* add pull request linting action and validation logic ([09380fb](https://git.kjan.de/actions/pull-request-lint/commit/09380fb8d002b200cebb4d56e8800569a0b60f16))
* **invoke-binary:** add ls command execution in runGo function ([da4a8b3](https://git.kjan.de/actions/pull-request-lint/commit/da4a8b3030406f5ba8c82093f2385060cd0d48b8))
## [0.2.1](https://git.kjan.de/actions/pull-request-lint/compare/v0.2.0...v0.2.1) (2025-04-09)
### Bug Fixes
* Fix release pipeline ([bc0bf00](https://git.kjan.de/actions/pull-request-lint/commit/bc0bf00947c563652b674cab947f863c5c477dd2))
# [0.2.0](https://git.kjan.de/actions/pull-request-lint/compare/v0.1.0...v0.2.0) (2025-04-09) # [0.2.0](https://git.kjan.de/actions/pull-request-lint/compare/v0.1.0...v0.2.0) (2025-04-09)

3
go.mod Normal file
View file

@ -0,0 +1,3 @@
module git.kjan.de/actions/pull-request-lint
go 1.24.2

0
go.sum Normal file
View file

View file

@ -0,0 +1,78 @@
// Package validation General validation tasks
package validation
import (
"fmt"
"regexp"
"strings"
)
// ValidateConventionalCommit validates if string follows conventional commit
func ValidateConventionalCommit(commit string) error {
// Regex to match the commit format
// type(scope)!: description
// or
// type!: description
// or
// type: description
re := regexp.MustCompile(`^(?P<type>[a-z]+)(?P<scope>\([a-z]+\))?(?P<breaking>!)?: (?P<description>.+)$`)
match := re.FindStringSubmatch(commit)
if len(match) == 0 {
return fmt.Errorf("invalid commit format")
}
typeIndex := re.SubexpIndex("type")
scopeIndex := re.SubexpIndex("scope")
breakingIndex := re.SubexpIndex("breaking")
commitType := match[typeIndex]
scope := match[scopeIndex]
breaking := match[breakingIndex]
// Type MUST be lowercase
if commitType != strings.ToLower(commitType) {
return fmt.Errorf("type must be lowercase")
}
// Scope MUST be lowercase
if scope != "" && scope != strings.ToLower(scope) {
return fmt.Errorf("scope must be lowercase")
}
// Check for breaking change indicator
hasBreakingChangeFooter := strings.Contains(commit, "BREAKING CHANGE:")
if breaking == "!" && hasBreakingChangeFooter {
return fmt.Errorf("breaking change indicator and footer are mutually exclusive")
}
lines := strings.Split(commit, "\n")
if len(lines) > 1 {
body := strings.Join(lines[1:], "\n")
// Check if body is separated from description by a blank line
if !strings.HasPrefix(body, "\n") {
return fmt.Errorf("body must be separated from description by a blank line")
}
}
// Check for footers
footerRegex := regexp.MustCompile(`(?m)^(?P<token>[A-Za-z-]+|BREAKING CHANGE): (?P<value>.*)$`)
footerMatches := footerRegex.FindAllStringSubmatch(commit, -1)
for _, footerMatch := range footerMatches {
tokenIndex := footerRegex.SubexpIndex("token")
token := footerMatch[tokenIndex]
// BREAKING-CHANGE MUST be synonymous with BREAKING CHANGE
if token == "BREAKING-CHANGE" {
continue
}
// Token MUST use - in place of whitespace characters, except for BREAKING CHANGE
if token != "BREAKING CHANGE" && strings.Contains(token, " ") {
return fmt.Errorf("footer token must use - in place of whitespace characters")
}
}
return nil
}

54
main.go Normal file
View file

@ -0,0 +1,54 @@
// Package main is the main package
package main
import (
"encoding/json"
"fmt"
"os"
"git.kjan.de/actions/pull-request-lint/internal/validation"
)
// GithubEvent represents a github actions event
type GithubEvent struct {
PullRequest struct {
Title string `json:"title"`
} `json:"pull_request"`
}
func main() {
eventPath := os.Getenv("GITHUB_EVENT_PATH")
if eventPath == "" {
fmt.Println("GITHUB_EVENT_PATH not set")
os.Exit(1)
}
eventFile, err := os.Open(eventPath)
if err != nil {
fmt.Printf("Error opening %s: %v\n", eventPath, err)
os.Exit(1)
}
defer func() {
closeFileErr := eventFile.Close()
if closeFileErr != nil {
fmt.Println("Error closing eventFile")
os.Exit(1)
}
}()
var event GithubEvent
decoder := json.NewDecoder(eventFile)
err = decoder.Decode(&event)
if err != nil {
fmt.Printf("Error decoding event.json: %v\n", err)
os.Exit(1)
}
prTitle := event.PullRequest.Title
semanticValidationErr := validation.ValidateConventionalCommit(prTitle)
if semanticValidationErr != nil {
fmt.Println(semanticValidationErr)
os.Exit(1)
}
os.Exit(0)
}

6
renovate.json Normal file
View file

@ -0,0 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"local>Renovate/renovate-config"
]
}