-
Notifications
You must be signed in to change notification settings - Fork 0
ci: add CI/CD automation workflows #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Add automated CI/CD pipeline: - ci.yml: tests, typecheck, coverage with Codecov - release-pr.yml: automated release PR creation - release-publish.yml: npm publish on PR merge via OIDC Signed-off-by: assagman <ahmetsercansagman@gmail.com>
Add wf-* targets for workflow management (wf-release, wf-ci, etc.) Update RELEASE.md with automated release process documentation Signed-off-by: assagman <ahmetsercansagman@gmail.com>
Add npm, coverage, CI status badges to README Complete CHANGELOG with full version history from v0.1.0 to v0.5.1 Signed-off-by: assagman <ahmetsercansagman@gmail.com>
Add repository, bugs, and homepage URLs for npm provenance Signed-off-by: assagman <ahmetsercansagman@gmail.com>
Summary of ChangesHello @assagman, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a robust CI/CD pipeline using GitHub Actions to automate critical development and release processes. The changes aim to enhance code quality through continuous integration, simplify the creation of release candidates, and automate the secure publishing of packages to npm. This automation reduces manual overhead, improves release consistency, and provides clearer documentation for the project's lifecycle. Highlights
Ignored Files
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
Welcome to Codecov 🎉Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests. ℹ️ You can also turn on project coverage checks and project coverage reporting on Pull Request comment Thanks for integrating Codecov - We've got you covered ☂️ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This is an excellent pull request that introduces comprehensive CI/CD automation, including workflows for testing, release PR creation, and automated publishing. The accompanying documentation in RELEASE.md is thorough and clear, and the Makefile helpers are a great addition for developer convenience. My review includes a couple of suggestions to improve the robustness of the new Makefile targets to make them more reliable in edge cases.
| # Workflows (requires gh cli + fzf) | ||
| # Trigger release PR workflow with interactive prompts | ||
| wf-release: | ||
| @TYPE=$$(echo -e "auto\npatch\nminor\nmajor" | fzf --prompt="Version type: " --height=6 --reverse); \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a user cancels the fzf prompt (e.g., by pressing Esc), the TYPE variable will be empty. The script then proceeds to call gh workflow run with an empty version_type, which is likely to fail with a potentially confusing error. It's more user-friendly to exit the target immediately if fzf is cancelled.
@TYPE=$$(echo -e "auto\npatch\nminor\nmajor" | fzf --prompt="Version type: " --height=6 --reverse) || exit; \
| sleep 2; \ | ||
| $(MAKE) wf-watch W=release-pr.yml |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a fixed sleep 2 before watching the workflow creates a race condition. The workflow run might not be available on GitHub's API within two seconds, which could cause the subsequent wf-watch command to fail. A more robust approach is to poll for the workflow run to appear for a short period before giving up.
This same improvement can be applied to the wf-publish (lines 87-88) and wf-ci (lines 93-94) targets.
@echo "Waiting for workflow to start..."; \
@for i in 1 2 3 4 5; do \
if LATEST_RUN_ID=$$(gh run list -w release-pr.yml -L 1 --json databaseId -q '.[0].databaseId') && [ -n "$$LATEST_RUN_ID" ] && [ "$$LATEST_RUN_ID" != "null" ]; then \
gh run watch $$LATEST_RUN_ID; \
exit 0; \
fi; \
sleep 2; \
done; \
echo "Error: Timed out waiting for workflow run to start." >&2; \
exit 1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds comprehensive CI/CD automation for the opencode-dotenv package, implementing workflows for continuous integration, automated release preparation, and npm publishing via OIDC trusted publisher authentication.
Changes:
- Added GitHub Actions workflows for CI (testing/coverage), release PR creation, and automated npm publishing
- Added Makefile helper targets for workflow management (requires gh CLI and fzf)
- Updated documentation with automated release process and added repository metadata
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
.github/workflows/ci.yml |
CI workflow for running tests, type checking, and uploading coverage to Codecov |
.github/workflows/release-pr.yml |
Workflow to create release PRs with automatic version bumping and CHANGELOG generation |
.github/workflows/release-publish.yml |
Workflow to publish to npm using OIDC, create tags, and GitHub releases when PRs merge |
Makefile |
Added workflow helper targets for triggering workflows and monitoring runs |
package.json |
Added repository metadata for npm provenance support |
RELEASE.md |
Comprehensive rewrite documenting the automated release process |
CHANGELOG.md |
Added complete version history and unreleased section for current changes |
README.md |
Added status badges for npm, CI, and code coverage |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Features (normalize case before sed to handle Feat/FEAT variants) | ||
| FEATURES=$(echo "$COMMITS" | grep -iE "^feat(\(.+\))?:" | tr '[:upper:]' '[:lower:]' | sed 's/^feat(\([^)]*\)): /- **\1**: /' | sed 's/^feat: /- /' || true) | ||
| if [ -n "$FEATURES" ]; then | ||
| ENTRY+="### Added"$'\n'"$FEATURES"$'\n\n' | ||
| fi | ||
| # Fixes (normalize case before sed to handle Fix/FIX variants) | ||
| FIXES=$(echo "$COMMITS" | grep -iE "^fix(\(.+\))?:" | tr '[:upper:]' '[:lower:]' | sed 's/^fix(\([^)]*\)): /- **\1**: /' | sed 's/^fix: /- /' || true) |
Copilot
AI
Jan 15, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sed regex patterns use \( and \) for capture groups, but after tr '[:upper:]' '[:lower:]' converts the commit prefix to lowercase, the pattern ^feat(\([^)]*\)) expects a literal opening parenthesis that's already lowercase 'feat('. However, the closing parenthesis in the sed pattern \([^)]*\) will correctly capture the scope. The issue is that after tr, the commit will be like 'feat(scope): message' but the sed pattern assumes 'feat(' is already matched by grep. This should work, but the double sed chaining could be simplified to a single sed with case-insensitive flag.
| # Features (normalize case before sed to handle Feat/FEAT variants) | |
| FEATURES=$(echo "$COMMITS" | grep -iE "^feat(\(.+\))?:" | tr '[:upper:]' '[:lower:]' | sed 's/^feat(\([^)]*\)): /- **\1**: /' | sed 's/^feat: /- /' || true) | |
| if [ -n "$FEATURES" ]; then | |
| ENTRY+="### Added"$'\n'"$FEATURES"$'\n\n' | |
| fi | |
| # Fixes (normalize case before sed to handle Fix/FIX variants) | |
| FIXES=$(echo "$COMMITS" | grep -iE "^fix(\(.+\))?:" | tr '[:upper:]' '[:lower:]' | sed 's/^fix(\([^)]*\)): /- **\1**: /' | sed 's/^fix: /- /' || true) | |
| # Features (handle Feat/FEAT variants with case-insensitive matching) | |
| FEATURES=$(echo "$COMMITS" | grep -iE "^feat(\(.+\))?:" | sed -E 's/^feat\(([^)]*)\): /- **\1**: /I; s/^feat: /- /I' || true) | |
| if [ -n "$FEATURES" ]; then | |
| ENTRY+="### Added"$'\n'"$FEATURES"$'\n\n' | |
| fi | |
| # Fixes (handle Fix/FIX variants with case-insensitive matching) | |
| FIXES=$(echo "$COMMITS" | grep -iE "^fix(\(.+\))?:" | sed -E 's/^fix\(([^)]*)\): /- **\1**: /I; s/^fix: /- /I' || true) |
| fi | ||
| # Fixes (normalize case before sed to handle Fix/FIX variants) | ||
| FIXES=$(echo "$COMMITS" | grep -iE "^fix(\(.+\))?:" | tr '[:upper:]' '[:lower:]' | sed 's/^fix(\([^)]*\)): /- **\1**: /' | sed 's/^fix: /- /' || true) |
Copilot
AI
Jan 15, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sed regex patterns use \( and \) for capture groups, but after tr '[:upper:]' '[:lower:]' converts the commit prefix to lowercase, the pattern ^feat(\([^)]*\)) expects a literal opening parenthesis that's already lowercase 'feat('. However, the closing parenthesis in the sed pattern \([^)]*\) will correctly capture the scope. The issue is that after tr, the commit will be like 'feat(scope): message' but the sed pattern assumes 'feat(' is already matched by grep. This should work, but the double sed chaining could be simplified to a single sed with case-insensitive flag.
| if [ "$$TYPE" = "auto" ]; then \ | ||
| read -p "Custom version (leave empty for auto): " VERSION; \ | ||
| fi; \ | ||
| echo "→ Triggering release: type=$$TYPE version=$${VERSION:-auto}"; \ |
Copilot
AI
Jan 15, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic prompts for a custom version only when type is 'auto', but the prompt message 'leave empty for auto' is confusing in this context. If the user selected 'auto', they probably don't want to provide a custom version. The custom version input should likely be prompted regardless of the selected type, or the conditional should check if type is NOT 'auto'. Consider prompting for custom version for all types or removing this conditional to make the UX clearer.
| if [ "$$TYPE" = "auto" ]; then \ | |
| read -p "Custom version (leave empty for auto): " VERSION; \ | |
| fi; \ | |
| echo "→ Triggering release: type=$$TYPE version=$${VERSION:-auto}"; \ | |
| if [ "$$TYPE" != "auto" ]; then \ | |
| read -p "Custom version (leave empty for auto): " VERSION; \ | |
| fi; \ | |
| echo "→ Triggering release: type=$$TYPE version=$${VERSION:-$$TYPE}"; \ |
| files: ./coverage/lcov.info | ||
| flags: unittests | ||
| name: codecov-umbrella | ||
| fail_ci_if_error: true |
Copilot
AI
Jan 15, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting fail_ci_if_error: true will cause the CI workflow to fail if Codecov upload fails. This can be problematic if Codecov has service issues or if the token is temporarily unavailable. Consider setting this to false to make CI more resilient to external service failures, or at least document this behavior in the setup documentation.
| fail_ci_if_error: true | |
| fail_ci_if_error: false |
| registry-url: 'https://registry.npmjs.org' | ||
|
|
||
| - name: Update npm for OIDC trusted publishing | ||
| run: npm install -g npm@latest |
Copilot
AI
Jan 15, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Installing npm@latest globally introduces unpredictability as the npm version will change over time. For better reproducibility and stability, consider pinning to a specific npm version (e.g., npm@10.2.5) or at least a major version range (e.g., npm@10).
| run: npm install -g npm@latest | |
| run: npm install -g npm@10 |
Summary
Changes
CI/CD Workflows
ci.ymlrelease-pr.ymlrelease-publish.ymlMakefile Targets
One-Time Setup Required
publishenvironment in repo settingsrelease-publish.ymlreleaseandautomatedlabelsCODECOV_TOKENsecret