mirror of
https://github.com/triqbit/mt5-ai-xauusd-trader.git
synced 2026-11-02 06:56:15 +00:00
feat: implement semantic versioning and automated release orchestration (#709)
- Added docs/VERSIONING_POLICY.md defining SemVer and Conventional Commit rules. - Implemented .github/workflows/changelog.yml for automated CHANGELOG.md updates. - Implemented .github/workflows/commit-check.yml to enforce PR title standards. - Updated .pre-commit-config.yaml with conventional-pre-commit hook. - Refined .github/workflows/release.yml with automated version bumping, file synchronization, and Docker tagging. - Updated CHANGELOG.md with proper template and [Unreleased] section. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: andonly1348 <279141437+andonly1348@users.noreply.github.com>
This commit is contained in:
co-authored by
google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
andonly1348
parent
9d1bf600e0
commit
d7a5ed25ea
@@ -4,10 +4,11 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths-ignore:
|
||||
- 'CHANGELOG.md'
|
||||
- 'docs/**'
|
||||
- '*.md'
|
||||
paths:
|
||||
- 'src/**'
|
||||
- 'main.py'
|
||||
- 'pyproject.toml'
|
||||
- 'requirements*.txt'
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
@@ -27,8 +28,6 @@ jobs:
|
||||
uses: Conventional-Changelog/github-action-generate-changelog@v1
|
||||
with:
|
||||
path-to-changelog: CHANGELOG.md
|
||||
# This action by default updates the Unreleased section if no tag is provided
|
||||
# or appends to the top.
|
||||
|
||||
- name: Commit and Push Changelog
|
||||
run: |
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
name: Commit Message Check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- synchronize
|
||||
|
||||
permissions:
|
||||
pull-requests: read
|
||||
|
||||
jobs:
|
||||
main:
|
||||
name: Validate PR Title
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: amannn/action-semantic-pull-request@v5
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
# Configure which types are allowed.
|
||||
types: |
|
||||
feat
|
||||
fix
|
||||
perf
|
||||
docs
|
||||
refactor
|
||||
style
|
||||
test
|
||||
chore
|
||||
ci
|
||||
# Configure that a scope must be always lowercase.
|
||||
subjectPattern: ^(?![A-Z]).+$
|
||||
# If the PR title contains a breaking change (!), it must be at the end of the type.
|
||||
# e.g. "feat!: breaking change"
|
||||
@@ -4,7 +4,7 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Version to release (e.g. 1.0.0). If empty, will be calculated from commits.'
|
||||
description: 'Version to release (e.g. 1.2.0). If empty, will be calculated from commits.'
|
||||
required: false
|
||||
prerelease:
|
||||
description: 'Is this a pre-release?'
|
||||
@@ -14,9 +14,6 @@ on:
|
||||
description: 'Dry run (do not tag or publish)'
|
||||
type: boolean
|
||||
default: false
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
@@ -140,22 +137,26 @@ jobs:
|
||||
needs: validate
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Calculate Version (for Docker tagging)
|
||||
id: tag_calc
|
||||
if: github.event.inputs.version == ''
|
||||
uses: mathieudutour/github-tag-action@v6.2
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
dry_run: true
|
||||
|
||||
- name: Determine Version
|
||||
id: version
|
||||
run: |
|
||||
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
|
||||
if [[ "${{ github.event.inputs.version }}" != "" ]]; then
|
||||
echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
|
||||
echo "TAG=v${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "VERSION=0.0.0-draft" >> $GITHUB_OUTPUT
|
||||
echo "TAG=v0.0.0-draft" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
if [[ "${{ github.event.inputs.version }}" != "" ]]; then
|
||||
echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
|
||||
echo "TAG=v${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
|
||||
else
|
||||
TAG="${GITHUB_REF#refs/tags/}"
|
||||
echo "TAG=$TAG" >> $GITHUB_OUTPUT
|
||||
echo "VERSION=${TAG#v}" >> $GITHUB_OUTPUT
|
||||
echo "VERSION=${{ steps.tag_calc.outputs.new_version }}" >> $GITHUB_OUTPUT
|
||||
echo "TAG=${{ steps.tag_calc.outputs.new_tag }}" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
@@ -189,44 +190,38 @@ jobs:
|
||||
name: Create Release
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
if: (github.event_name == 'workflow_dispatch' && github.event.inputs.dry_run == 'false') || startsWith(github.ref, 'refs/tags/v')
|
||||
if: github.event_name == 'workflow_dispatch' && github.event.inputs.dry_run == 'false'
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Calculate Next Version
|
||||
id: tag_action
|
||||
if: github.event_name == 'workflow_dispatch' && github.event.inputs.version == ''
|
||||
if: github.event.inputs.version == ''
|
||||
uses: mathieudutour/github-tag-action@v6.2
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
dry_run: true
|
||||
create_tag: false
|
||||
|
||||
- name: Determine Version
|
||||
id: version
|
||||
run: |
|
||||
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
|
||||
if [[ "${{ github.event.inputs.version }}" != "" ]]; then
|
||||
echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
|
||||
echo "TAG=v${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "VERSION=${{ steps.tag_action.outputs.new_version }}" >> $GITHUB_OUTPUT
|
||||
echo "TAG=${{ steps.tag_action.outputs.new_tag }}" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
if [[ "${{ github.event.inputs.version }}" != "" ]]; then
|
||||
echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
|
||||
echo "TAG=v${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
|
||||
else
|
||||
TAG="${GITHUB_REF#refs/tags/}"
|
||||
echo "TAG=$TAG" >> $GITHUB_OUTPUT
|
||||
echo "VERSION=${TAG#v}" >> $GITHUB_OUTPUT
|
||||
echo "VERSION=${{ steps.tag_action.outputs.new_version }}" >> $GITHUB_OUTPUT
|
||||
echo "TAG=${{ steps.tag_action.outputs.new_tag }}" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Update Version and Changelog
|
||||
if: github.event_name == 'workflow_dispatch' && github.event.inputs.dry_run == 'false'
|
||||
run: |
|
||||
VERSION="${{ steps.version.outputs.VERSION }}"
|
||||
DATE=$(date +%Y-%m-%d)
|
||||
|
||||
# Update version strings using a shared variable
|
||||
echo "Updating version to ${VERSION} in pyproject.toml and src/__init__.py"
|
||||
sed -i "s/^version = \".*\"/version = \"${VERSION}\"/" pyproject.toml
|
||||
|
||||
@@ -247,8 +242,7 @@ jobs:
|
||||
git push origin main
|
||||
fi
|
||||
|
||||
- name: Create Git Tag (if manual)
|
||||
if: github.event_name == 'workflow_dispatch' && github.event.inputs.dry_run == 'false'
|
||||
- name: Create Git Tag
|
||||
run: |
|
||||
TAG="${{ steps.version.outputs.TAG }}"
|
||||
git config user.name "github-actions[bot]"
|
||||
|
||||
@@ -51,3 +51,13 @@ repos:
|
||||
name: pip-audit (dependency safety)
|
||||
args:
|
||||
- --requirement=requirements-ci.txt
|
||||
|
||||
# -----------------------------------------------------------
|
||||
# 4. Conventional Commits — enforce commit message format
|
||||
# -----------------------------------------------------------
|
||||
- repo: https://github.com/compilerla/conventional-pre-commit
|
||||
rev: v3.2.0
|
||||
hooks:
|
||||
- id: conventional-pre-commit
|
||||
stages: [commit-msg]
|
||||
args: [feat, fix, perf, docs, refactor, style, test, chore, ci]
|
||||
|
||||
@@ -45,7 +45,13 @@ To enable automated changelog generation and version bumping, all commits to the
|
||||
Indicate a breaking change by adding a `!` after the type/scope or by adding `BREAKING CHANGE:` in the footer of the commit message. This triggers a **MAJOR** version bump.
|
||||
*Example*: `feat!: overhaul risk management engine`
|
||||
|
||||
## 3. Tagging & Release Strategy
|
||||
## 3. Pull Request Labels (Optional)
|
||||
While Conventional Commits are the primary driver, PR labels can be used to override or supplement automation:
|
||||
- `release:major`: Forces a MAJOR version bump.
|
||||
- `release:minor`: Forces a MINOR version bump.
|
||||
- `release:patch`: Forces a PATCH version bump.
|
||||
|
||||
## 4. Tagging & Release Strategy
|
||||
|
||||
### Stable Releases
|
||||
- **Branch**: `main`
|
||||
@@ -61,16 +67,18 @@ Indicate a breaking change by adding a `!` after the type/scope or by adding `BR
|
||||
- **Tag Format**: `vMAJOR.MINOR.PATCH-alpha.N` or `vMAJOR.MINOR.PATCH-beta.N`
|
||||
- **Use Case**: Early testing of experimental features.
|
||||
|
||||
## 4. Automated Workflow
|
||||
## 5. Automated Workflow
|
||||
|
||||
1. **Automated Changelog**: Every push to `main` triggers the `changelog.yml` workflow, which appends new conventional commits to the `CHANGELOG.md` file under the `[Unreleased]` section.
|
||||
2. **Version Bump Automation**: The `Release Orchestration` (`release.yml`) workflow:
|
||||
- Calculates the next version based on commit history if not manually provided.
|
||||
2. **Commit Validation**: Every Pull Request is checked by the `commit-check.yml` workflow to ensure it meets Conventional Commit standards.
|
||||
3. **Local Enforcement**: A pre-commit hook ensures that local commits adhere to the standard before they are even pushed.
|
||||
4. **Version Bump Automation**: The `Release Orchestration` (`release.yml`) workflow:
|
||||
- Calculates the next version based on commit history.
|
||||
- Updates `pyproject.toml` and `src/__init__.py`.
|
||||
- Transitions `[Unreleased]` content in `CHANGELOG.md` to a new versioned header.
|
||||
- Creates a new Git tag and GitHub Release.
|
||||
|
||||
## 5. Guidance for Version Bumping
|
||||
## 6. Guidance for Version Bumping
|
||||
|
||||
| Change Type | Version Component | Example Commit |
|
||||
| :--- | :--- | :--- |
|
||||
|
||||
Reference in New Issue
Block a user