Skip to content

Commit eb8b869

Browse files
authored
feat: improve CICD pipeline (#84)
* fix(makefile): update formatting tasks and correct documentation path * fix(ci): update checkout action version and improve node setup * chore(release): update release workflow and improve caching strategies * ci: add GitHub Actions workflow for Markdown linting in docs * fix(ci): update checkout action version and configure Node.js setup * fix(ci): update Node.js setup action to version 4 * ci: update documentation linting commands to use npx and add Rust API documentation build task * ci: enhance documentation workflows with Rust API documentation publishing * ci(docs): allow Markdown linting to continue on error * ci(gh-pages): add GitHub Pages deployment workflow * ci(docs): add API index redirect generation to documentation workflow * ci(gh-pages): trigger deployment on completion of documentation workflows * ci(gh-pages): update branch syntax for consistency * ci(gh-pages): specify branch reference and fetch depth in checkout step * ci(docs): update documentation build script to use release profile * ci: update CI configuration to use rust-cache for improved build performance * ci: streamline CI configuration by removing unnecessary steps and optimizing node setup * ci: add workflow for building and publishing Rust API documentation * ci(gh-pages): update workflow reference from Docs to RustDoc * ci: remove conditional check for pull requests in rustdoc publishing * ci: update rust-cache usage and remove redundant cache steps * ci: enhance caching for Cargo tooling * ci: add version check before tagging * ci: improve logging for version checks and tag creation * ci: harden permissions for contents and packages * ci: add continuous deployment workflow for versioned releases * chore: remove unused workflow * chore: remove unused workflow * ci: add concurrency and version validation * ci: add API docs publishing * chore: bump version to 0.0.3 * ci: update workflow trigger conditions for GH Pages deployment * ci: update workflow triggers * chore: downgrade version to 0.0.2 * docs: update CI/CD documentation to include new workflows and deployment processes
1 parent 2986f26 commit eb8b869

7 files changed

Lines changed: 341 additions & 129 deletions

File tree

.github/workflows/cd.yml

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
name: CD
2+
3+
on:
4+
workflow_run:
5+
workflows: ["CI"]
6+
types:
7+
- completed
8+
branches: [main]
9+
workflow_dispatch:
10+
11+
permissions:
12+
contents: write
13+
packages: write
14+
15+
concurrency:
16+
group: release-${{ github.ref }}
17+
cancel-in-progress: true
18+
19+
jobs:
20+
release:
21+
runs-on: ubuntu-latest
22+
# Only run if CI workflow completed successfully
23+
if: github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch'
24+
steps:
25+
- uses: actions/checkout@v5
26+
with:
27+
fetch-depth: 0
28+
29+
- name: Fetch all tags from origin
30+
run: |
31+
git fetch --tags --force --prune --no-recurse-submodules
32+
33+
- name: Extract version from Cargo.toml
34+
id: cargo_version
35+
run: |
36+
version=$(grep '^version' src/core/Cargo.toml | head -n1 | awk -F\" '{print $2}')
37+
echo "version=$version" >> $GITHUB_OUTPUT
38+
39+
- name: Check if version was bumped
40+
id: version_check
41+
run: |
42+
current_version="${{ steps.cargo_version.outputs.version }}"
43+
echo "Current version: $current_version"
44+
45+
# Ensure version follows strict semver (MAJOR.MINOR.PATCH)
46+
if ! echo "$current_version" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'; then
47+
echo "::error::Version '$current_version' is not valid semver (expected MAJOR.MINOR.PATCH like 1.2.3)"
48+
echo "should_release=false" >> $GITHUB_OUTPUT
49+
exit 1
50+
fi
51+
52+
# Get the latest tag, if any exists (after fetching tags)
53+
latest_tag=$(git tag -l "v*" --sort=-version:refname | head -n1)
54+
55+
if [ -z "$latest_tag" ]; then
56+
echo "No previous tags found, proceeding with first release"
57+
echo "should_release=true" >> $GITHUB_OUTPUT
58+
echo "previous_version=" >> $GITHUB_OUTPUT
59+
else
60+
# Extract version from tag (remove 'v' prefix)
61+
latest_version="${latest_tag#v}"
62+
echo "Latest tagged version: $latest_version"
63+
echo "previous_version=$latest_version" >> $GITHUB_OUTPUT
64+
65+
# Check if current version is greater than latest version
66+
if [ "$current_version" = "$latest_version" ]; then
67+
echo "::warning::Version $current_version already exists as tag $latest_tag"
68+
echo "Skipping release - no version bump detected"
69+
echo "should_release=false" >> $GITHUB_OUTPUT
70+
exit 0
71+
elif printf '%s\n%s\n' "$latest_version" "$current_version" | sort -V -C; then
72+
echo "::notice:: Version bumped from $latest_version to $current_version"
73+
echo "should_release=true" >> $GITHUB_OUTPUT
74+
else
75+
echo "::error::Version $current_version is not greater than latest version $latest_version"
76+
echo "Please ensure you're bumping the version correctly (following semver)"
77+
echo "should_release=false" >> $GITHUB_OUTPUT
78+
exit 1
79+
fi
80+
fi
81+
82+
- name: Download build artifacts from CI
83+
if: steps.version_check.outputs.should_release == 'true'
84+
uses: dawidd6/action-download-artifact@v3
85+
with:
86+
github_token: ${{ secrets.GITHUB_TOKEN }}
87+
workflow: ci.yml
88+
run_id: ${{ github.event.workflow_run.id }}
89+
name: build-output
90+
path: ./artifacts
91+
92+
- name: Create and push tag
93+
if: steps.version_check.outputs.should_release == 'true'
94+
env:
95+
GH_PAT: ${{ secrets.GH_PAT }}
96+
run: |
97+
git config user.name "github-actions"
98+
git config user.email "github-actions@github.com"
99+
tag_name="v${{ steps.cargo_version.outputs.version }}"
100+
101+
# Double-check tag doesn't exist remotely
102+
if git ls-remote --tags origin | grep -q "refs/tags/$tag_name$"; then
103+
echo "::error::Tag $tag_name already exists on remote"
104+
exit 1
105+
fi
106+
107+
git tag "$tag_name"
108+
git push https://x-access-token:${GH_PAT}@github.com/${GITHUB_REPOSITORY}.git "$tag_name"
109+
echo "::notice:: Successfully created and pushed tag $tag_name"
110+
111+
- name: Create GitHub Release
112+
if: steps.version_check.outputs.should_release == 'true'
113+
uses: softprops/action-gh-release@v2
114+
with:
115+
tag_name: v${{ steps.cargo_version.outputs.version }}
116+
name: Release v${{ steps.cargo_version.outputs.version }}
117+
body: |
118+
## What's Changed
119+
- Release version ${{ steps.cargo_version.outputs.version }}
120+
121+
## Download
122+
Download the `miel` binary for Linux x64.
123+
124+
**Full Changelog**: https://github.com/${{ github.repository }}/compare/v${{ steps.version_check.outputs.previous_version }}...v${{ steps.cargo_version.outputs.version }}
125+
files: |
126+
artifacts/miel
127+
draft: false
128+
prerelease: false

.github/workflows/ci.yml

Lines changed: 25 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ on:
1111
workflow_dispatch:
1212

1313
permissions:
14-
contents: write
15-
packages: write
14+
contents: read
15+
packages: read
1616
security-events: write
1717

1818
jobs:
@@ -22,21 +22,22 @@ jobs:
2222
- uses: actions/checkout@v5
2323
- uses: dtolnay/rust-toolchain@stable
2424
- uses: davidB/rust-cargo-make@v1
25-
- uses: actions/setup-node@v3
25+
- uses: swatinem/rust-cache@v2
26+
with:
27+
workspaces: |
28+
src/core -> src/core/target
29+
- uses: actions/cache@v4
30+
with:
31+
path: ~/.cargo/bin
32+
key: ${{ runner.os }}-cargo-tools-${{ hashFiles('**/Cargo.lock', '**/Cargo.toml') }}
33+
restore-keys: |
34+
${{ runner.os }}-cargo-tools-
35+
- uses: actions/setup-node@v4
2636
with:
2737
node-version-file: .nvmrc
2838
cache: npm
2939
cache-dependency-path: src/webui/package-lock.json
3040

31-
- uses: actions/cache@v3
32-
with:
33-
path: |
34-
~/.cargo/registry
35-
~/.cargo/git
36-
~/.cargo/bin
37-
target
38-
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
39-
4041
- name: Install cargo-audit if missing
4142
run: if ! command -v cargo-audit >/dev/null 2>&1; then cargo install cargo-audit; fi
4243

@@ -70,21 +71,16 @@ jobs:
7071
- uses: actions/checkout@v5
7172
- uses: dtolnay/rust-toolchain@stable
7273
- uses: davidB/rust-cargo-make@v1
73-
- uses: actions/setup-node@v3
74+
- uses: swatinem/rust-cache@v2
75+
with:
76+
workspaces: |
77+
src/core -> src/core/target
78+
- uses: actions/setup-node@v4
7479
with:
7580
node-version-file: .nvmrc
7681
cache: npm
7782
cache-dependency-path: src/webui/package-lock.json
7883

79-
- uses: actions/cache@v3
80-
with:
81-
path: |
82-
~/.cargo/registry
83-
~/.cargo/git
84-
~/.cargo/bin
85-
target
86-
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
87-
8884
- name: Run Rust tests
8985
run: cargo make core-test
9086

@@ -97,21 +93,17 @@ jobs:
9793
steps:
9894
- uses: actions/checkout@v5
9995
- uses: dtolnay/rust-toolchain@stable
100-
- uses: actions/setup-node@v3
96+
- uses: davidB/rust-cargo-make@v1
97+
- uses: swatinem/rust-cache@v2
98+
with:
99+
workspaces: |
100+
src/core -> src/core/target
101+
- uses: actions/setup-node@v4
101102
with:
102103
node-version-file: .nvmrc
103104
cache: npm
104105
cache-dependency-path: src/webui/package-lock.json
105106

106-
- uses: actions/cache@v3
107-
with:
108-
path: |
109-
~/.cargo/registry
110-
~/.cargo/git
111-
~/.cargo/bin
112-
target
113-
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
114-
115107
- name: Build production binary
116108
run: cargo make prod
117109

@@ -120,26 +112,4 @@ jobs:
120112
with:
121113
name: build-output
122114
path: src/core/target/release/miel
123-
124-
release:
125-
runs-on: ubuntu-latest
126-
needs: build
127-
if: github.ref == 'refs/heads/main'
128-
steps:
129-
- name: Checkout code
130-
uses: actions/checkout@v5
131-
132-
- name: Extract version from Cargo.toml
133-
id: cargo_version
134-
run: |
135-
version=$(grep '^version' src/core/Cargo.toml | head -n1 | awk -F\" '{print $2}')
136-
echo "version=$version" >> $GITHUB_OUTPUT
137-
138-
- name: Create and push tag
139-
env:
140-
GH_PAT: ${{ secrets.GH_PAT }}
141-
run: |
142-
git config user.name "github-actions"
143-
git config user.email "github-actions@github.com"
144-
git tag "v${{ steps.cargo_version.outputs.version }}"
145-
git push https://x-access-token:${GH_PAT}@github.com/${GITHUB_REPOSITORY}.git "v${{ steps.cargo_version.outputs.version }}"
115+
retention-days: 7

.github/workflows/docs.yml

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
name: Docs
2+
3+
on:
4+
workflow_run:
5+
workflows: [ "CI" ]
6+
types:
7+
- completed
8+
branches: [ main ]
9+
pull_request:
10+
paths:
11+
- "docs/**"
12+
- "src/core/**"
13+
push:
14+
branches: [ main, dev ]
15+
paths:
16+
- "docs/**"
17+
- "src/core/**"
18+
workflow_dispatch:
19+
20+
permissions:
21+
contents: write
22+
23+
concurrency:
24+
group: docs-${{ github.ref }}
25+
cancel-in-progress: true
26+
27+
jobs:
28+
changes:
29+
runs-on: ubuntu-latest
30+
outputs:
31+
docs: ${{ steps.filter.outputs.docs }}
32+
steps:
33+
- uses: actions/checkout@v5
34+
with:
35+
fetch-depth: 0
36+
- id: filter
37+
uses: dorny/paths-filter@v3
38+
with:
39+
filters: |
40+
docs:
41+
- 'docs/**'
42+
43+
lint-docs:
44+
runs-on: ubuntu-latest
45+
needs: changes
46+
if: needs.changes.outputs.docs == 'true'
47+
steps:
48+
- uses: actions/checkout@v5
49+
- uses: davidB/rust-cargo-make@v1
50+
- uses: swatinem/rust-cache@v2
51+
with:
52+
workspaces: |
53+
src/core -> target
54+
- uses: actions/setup-node@v4
55+
with:
56+
node-version-file: .nvmrc
57+
cache: npm
58+
cache-dependency-path: src/webui/package-lock.json
59+
60+
- name: Lint Markdown documentation
61+
run: cargo make doc-lint
62+
63+
build-api-docs:
64+
name: Build and publish Rust API docs
65+
runs-on: ubuntu-latest
66+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
67+
steps:
68+
- uses: actions/checkout@v4
69+
- uses: dtolnay/rust-toolchain@stable
70+
- uses: davidB/rust-cargo-make@v1
71+
- uses: swatinem/rust-cache@v2
72+
with:
73+
workspaces: |
74+
src/core -> src/core/target
75+
76+
- name: Build Rust API docs
77+
run: cargo make core-doc
78+
79+
- name: Create API index redirect
80+
run: |
81+
cat > src/core/target/doc/index.html << 'EOF'
82+
<!DOCTYPE html>
83+
<html>
84+
<head>
85+
<meta charset="utf-8">
86+
<title>Miel API Documentation</title>
87+
<meta http-equiv="refresh" content="0; url=miel/">
88+
<link rel="canonical" href="miel/">
89+
</head>
90+
<body>
91+
<p>Redirecting to <a href="miel/">Miel API Documentation</a>...</p>
92+
</body>
93+
</html>
94+
EOF
95+
96+
- name: Publish rustdoc to gh-pages/api
97+
uses: peaceiris/actions-gh-pages@v3
98+
with:
99+
github_token: ${{ secrets.GITHUB_TOKEN }}
100+
publish_branch: gh-pages
101+
publish_dir: src/core/target/doc
102+
destination_dir: api
103+
keep_files: true
104+
user_name: github-actions[bot]
105+
user_email: 41898282+github-actions[bot]@users.noreply.github.com

0 commit comments

Comments
 (0)