Skip to content

refactor: deduplicate CI workflows and fix double triggers#141

Merged
Junyi-99 merged 2 commits intomainfrom
refactor/deduplicate-ci-workflows-main
Mar 28, 2026
Merged

refactor: deduplicate CI workflows and fix double triggers#141
Junyi-99 merged 2 commits intomainfrom
refactor/deduplicate-ci-workflows-main

Conversation

@Junyi-99
Copy link
Copy Markdown
Member

Extract reusable workflows (_build-backend.yml, _build-ext.yml) to
eliminate duplicated build/deploy logic across dev/stg/prd. Remove
push: tags: v* trigger from stg/prd backend workflows to prevent
double builds (bump-version already dispatches via repository_dispatch).
Delete the no-op build-ext-dev.yml.

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com

Junyi Hou and others added 2 commits March 28, 2026 14:48
Extract reusable workflows (_build-backend.yml, _build-ext.yml) to
eliminate duplicated build/deploy logic across dev/stg/prd. Remove
`push: tags: v*` trigger from stg/prd backend workflows to prevent
double builds (bump-version already dispatches via repository_dispatch).
Delete the no-op build-ext-dev.yml.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When mongo.in_cluster is true, PD_MONGO_URI was not set in the
configmap, causing the Go app to fall back to localhost:27017
which doesn't work inside the cluster. Now uses the FQDN
mongo.<namespace>.svc.cluster.local with the replicaSet parameter.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 28, 2026 06:59
@Junyi-99 Junyi-99 merged commit 5d5b595 into main Mar 28, 2026
@Junyi-99 Junyi-99 deleted the refactor/deduplicate-ci-workflows-main branch March 28, 2026 06:59
@Junyi-99 Junyi-99 restored the refactor/deduplicate-ci-workflows-main branch March 28, 2026 06:59
@Junyi-99 Junyi-99 deleted the refactor/deduplicate-ci-workflows-main branch March 28, 2026 07:00
Copy link
Copy Markdown
Contributor

Copilot AI left a 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 refactors the CI/CD GitHub Actions setup by extracting duplicated backend/extension build logic into reusable workflows, and adjusts triggers to prevent duplicate backend builds for stg/prd. It also updates the Helm chart to set PD_MONGO_URI based on whether MongoDB runs in-cluster.

Changes:

  • Add reusable workflows (_build-backend.yml, _build-ext.yml) and switch env-specific workflows to call them.
  • Remove push: tags: v* triggers from stg/prd backend workflows to avoid double builds (rely on repository_dispatch).
  • Update Helm template to always set PD_MONGO_URI, including an in-cluster MongoDB URI.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
helm-chart/templates/paperdebugger.yaml Sets PD_MONGO_URI based on mongo.in_cluster (in-cluster vs external).
.github/workflows/_build-backend.yml New reusable workflow for backend build + deploy across dev/stg/prd.
.github/workflows/_build-ext.yml New reusable workflow for Chrome extension build + upload.
.github/workflows/build-backend-dev.yml Refactored to call _build-backend.yml for dev.
.github/workflows/build-backend-stg.yml Refactored to call _build-backend.yml for stg; tag push trigger removed.
.github/workflows/build-backend-prd.yml Refactored to call _build-backend.yml for prd; tag push trigger removed.
.github/workflows/build-ext-stg.yml Refactored to call _build-ext.yml for stg.
.github/workflows/build-ext-prd.yml Refactored to call _build-ext.yml for prd.
.github/workflows/build-ext-dev.yml Deleted (previously a no-op “unsupported” workflow).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +79 to +83
{{- if .Values.mongo.in_cluster }}
PD_MONGO_URI: "mongodb://mongo.{{ .Values.namespace }}.svc.cluster.local:27017/?replicaSet=in-cluster"
{{- else }}
PD_MONGO_URI: "{{ .Values.mongo.uri }}"
{{ end }} No newline at end of file
{{- end }} No newline at end of file
Copy link

Copilot AI Mar 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This Helm chart change (Mongo URI selection) is not mentioned in the PR description, which focuses on CI workflow deduplication/double triggers. Please confirm this is intended scope (or split it into a separate PR) so the deployment/CI refactor can be reviewed and rolled out independently.

Copilot uses AI. Check for mistakes.
JWT_SIGNING_KEY: "{{ .Values.jwt_signing_key }}"
{{ if not .Values.mongo.in_cluster }}
{{- if .Values.mongo.in_cluster }}
PD_MONGO_URI: "mongodb://mongo.{{ .Values.namespace }}.svc.cluster.local:27017/?replicaSet=in-cluster"
Copy link

Copilot AI Mar 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PD_MONGO_URI hardcodes the Kubernetes cluster DNS suffix as svc.cluster.local. That suffix is configurable on many clusters, so this may break name resolution outside the default cluster domain. Prefer using the service DNS name (mongo:27017 or mongo.<namespace>.svc) or make the cluster domain configurable via values.

Suggested change
PD_MONGO_URI: "mongodb://mongo.{{ .Values.namespace }}.svc.cluster.local:27017/?replicaSet=in-cluster"
PD_MONGO_URI: "mongodb://mongo.{{ .Values.namespace }}.svc.{{ .Values.clusterDomain | default \"cluster.local\" }}:27017/?replicaSet=in-cluster"

Copilot uses AI. Check for mistakes.
Comment on lines +64 to +77
- name: Generate kubernetes manifests
env:
OPENAI_BASE_URL: ${{ inputs.environment == 'dev' && secrets.OPENAI_BASE_URL_DEV || inputs.environment == 'stg' && secrets.OPENAI_BASE_URL_STG || secrets.OPENAI_BASE_URL_PRD }}
OPENAI_API_KEY: ${{ inputs.environment == 'dev' && secrets.OPENAI_API_KEY_DEV || inputs.environment == 'stg' && secrets.OPENAI_API_KEY_STG || secrets.OPENAI_API_KEY_PRD }}
INFERENCE_BASE_URL: ${{ inputs.environment == 'dev' && secrets.INFERENCE_BASE_URL_DEV || inputs.environment == 'stg' && secrets.INFERENCE_BASE_URL_STG || secrets.INFERENCE_BASE_URL_PRD }}
INFERENCE_API_KEY: ${{ inputs.environment == 'dev' && secrets.INFERENCE_API_KEY_DEV || inputs.environment == 'stg' && secrets.INFERENCE_API_KEY_STG || secrets.INFERENCE_API_KEY_PRD }}
MCP_BASIC_KEY: ${{ inputs.environment == 'dev' && secrets.MCP_BASIC_KEY_DEV || inputs.environment == 'stg' && secrets.MCP_BASIC_KEY_STG || secrets.MCP_BASIC_KEY_PRD }}
MCP_PAPERSCORE_KEY: ${{ inputs.environment == 'dev' && secrets.MCP_PAPERSCORE_KEY_DEV || inputs.environment == 'stg' && secrets.MCP_PAPERSCORE_KEY_STG || secrets.MCP_PAPERSCORE_KEY_PRD }}
XTRAMCP_OPENAI_BASE_URL: ${{ inputs.environment == 'dev' && secrets.XTRAMCP_OPENAI_BASE_URL_DEV || inputs.environment == 'stg' && secrets.XTRAMCP_OPENAI_BASE_URL_STG || secrets.XTRAMCP_OPENAI_BASE_URL_PRD }}
XTRAMCP_OPENAI_API_KEY: ${{ inputs.environment == 'dev' && secrets.XTRAMCP_OPENAI_API_KEY_DEV || inputs.environment == 'stg' && secrets.XTRAMCP_OPENAI_API_KEY_STG || secrets.XTRAMCP_OPENAI_API_KEY_PRD }}
XTRAMCP_OPENREVIEW_BASE_URL: ${{ inputs.environment == 'dev' && secrets.XTRAMCP_OPENREVIEW_BASE_URL_DEV || inputs.environment == 'stg' && secrets.XTRAMCP_OPENREVIEW_BASE_URL_STG || secrets.XTRAMCP_OPENREVIEW_BASE_URL_PRD }}
XTRAMCP_OPENREVIEW_USERNAME: ${{ inputs.environment == 'dev' && secrets.XTRAMCP_OPENREVIEW_USERNAME_DEV || inputs.environment == 'stg' && secrets.XTRAMCP_OPENREVIEW_USERNAME_STG || secrets.XTRAMCP_OPENREVIEW_USERNAME_PRD }}
XTRAMCP_OPENREVIEW_PASSWORD: ${{ inputs.environment == 'dev' && secrets.XTRAMCP_OPENREVIEW_PASSWORD_DEV || inputs.environment == 'stg' && secrets.XTRAMCP_OPENREVIEW_PASSWORD_STG || secrets.XTRAMCP_OPENREVIEW_PASSWORD_PRD }}
XTRAMCP_CROSSREF_EMAIL_ADDRESS: ${{ inputs.environment == 'dev' && secrets.XTRAMCP_CROSSREF_EMAIL_ADDRESS_DEV || inputs.environment == 'stg' && secrets.XTRAMCP_CROSSREF_EMAIL_ADDRESS_STG || secrets.XTRAMCP_CROSSREF_EMAIL_ADDRESS_PRD }}
Copy link

Copilot AI Mar 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reusable backend workflow selects secrets via dev || stg || prd short-circuit expressions; any unexpected inputs.environment value will silently fall back to PRD secrets. Add an explicit validation/guard (fail fast) or an explicit == 'prd' branch to avoid accidental PRD deployments with the wrong environment input.

Suggested change
- name: Generate kubernetes manifests
env:
OPENAI_BASE_URL: ${{ inputs.environment == 'dev' && secrets.OPENAI_BASE_URL_DEV || inputs.environment == 'stg' && secrets.OPENAI_BASE_URL_STG || secrets.OPENAI_BASE_URL_PRD }}
OPENAI_API_KEY: ${{ inputs.environment == 'dev' && secrets.OPENAI_API_KEY_DEV || inputs.environment == 'stg' && secrets.OPENAI_API_KEY_STG || secrets.OPENAI_API_KEY_PRD }}
INFERENCE_BASE_URL: ${{ inputs.environment == 'dev' && secrets.INFERENCE_BASE_URL_DEV || inputs.environment == 'stg' && secrets.INFERENCE_BASE_URL_STG || secrets.INFERENCE_BASE_URL_PRD }}
INFERENCE_API_KEY: ${{ inputs.environment == 'dev' && secrets.INFERENCE_API_KEY_DEV || inputs.environment == 'stg' && secrets.INFERENCE_API_KEY_STG || secrets.INFERENCE_API_KEY_PRD }}
MCP_BASIC_KEY: ${{ inputs.environment == 'dev' && secrets.MCP_BASIC_KEY_DEV || inputs.environment == 'stg' && secrets.MCP_BASIC_KEY_STG || secrets.MCP_BASIC_KEY_PRD }}
MCP_PAPERSCORE_KEY: ${{ inputs.environment == 'dev' && secrets.MCP_PAPERSCORE_KEY_DEV || inputs.environment == 'stg' && secrets.MCP_PAPERSCORE_KEY_STG || secrets.MCP_PAPERSCORE_KEY_PRD }}
XTRAMCP_OPENAI_BASE_URL: ${{ inputs.environment == 'dev' && secrets.XTRAMCP_OPENAI_BASE_URL_DEV || inputs.environment == 'stg' && secrets.XTRAMCP_OPENAI_BASE_URL_STG || secrets.XTRAMCP_OPENAI_BASE_URL_PRD }}
XTRAMCP_OPENAI_API_KEY: ${{ inputs.environment == 'dev' && secrets.XTRAMCP_OPENAI_API_KEY_DEV || inputs.environment == 'stg' && secrets.XTRAMCP_OPENAI_API_KEY_STG || secrets.XTRAMCP_OPENAI_API_KEY_PRD }}
XTRAMCP_OPENREVIEW_BASE_URL: ${{ inputs.environment == 'dev' && secrets.XTRAMCP_OPENREVIEW_BASE_URL_DEV || inputs.environment == 'stg' && secrets.XTRAMCP_OPENREVIEW_BASE_URL_STG || secrets.XTRAMCP_OPENREVIEW_BASE_URL_PRD }}
XTRAMCP_OPENREVIEW_USERNAME: ${{ inputs.environment == 'dev' && secrets.XTRAMCP_OPENREVIEW_USERNAME_DEV || inputs.environment == 'stg' && secrets.XTRAMCP_OPENREVIEW_USERNAME_STG || secrets.XTRAMCP_OPENREVIEW_USERNAME_PRD }}
XTRAMCP_OPENREVIEW_PASSWORD: ${{ inputs.environment == 'dev' && secrets.XTRAMCP_OPENREVIEW_PASSWORD_DEV || inputs.environment == 'stg' && secrets.XTRAMCP_OPENREVIEW_PASSWORD_STG || secrets.XTRAMCP_OPENREVIEW_PASSWORD_PRD }}
XTRAMCP_CROSSREF_EMAIL_ADDRESS: ${{ inputs.environment == 'dev' && secrets.XTRAMCP_CROSSREF_EMAIL_ADDRESS_DEV || inputs.environment == 'stg' && secrets.XTRAMCP_CROSSREF_EMAIL_ADDRESS_STG || secrets.XTRAMCP_CROSSREF_EMAIL_ADDRESS_PRD }}
- name: Validate environment input
run: |
if [ "${{ inputs.environment }}" != "dev" ] && [ "${{ inputs.environment }}" != "stg" ] && [ "${{ inputs.environment }}" != "prd" ]; then
echo "Invalid environment: ${{ inputs.environment }}. Must be one of: dev, stg, prd."
exit 1
fi
- name: Generate kubernetes manifests
env:
OPENAI_BASE_URL: ${{ inputs.environment == 'dev' && secrets.OPENAI_BASE_URL_DEV || inputs.environment == 'stg' && secrets.OPENAI_BASE_URL_STG || inputs.environment == 'prd' && secrets.OPENAI_BASE_URL_PRD }}
OPENAI_API_KEY: ${{ inputs.environment == 'dev' && secrets.OPENAI_API_KEY_DEV || inputs.environment == 'stg' && secrets.OPENAI_API_KEY_STG || inputs.environment == 'prd' && secrets.OPENAI_API_KEY_PRD }}
INFERENCE_BASE_URL: ${{ inputs.environment == 'dev' && secrets.INFERENCE_BASE_URL_DEV || inputs.environment == 'stg' && secrets.INFERENCE_BASE_URL_STG || inputs.environment == 'prd' && secrets.INFERENCE_BASE_URL_PRD }}
INFERENCE_API_KEY: ${{ inputs.environment == 'dev' && secrets.INFERENCE_API_KEY_DEV || inputs.environment == 'stg' && secrets.INFERENCE_API_KEY_STG || inputs.environment == 'prd' && secrets.INFERENCE_API_KEY_PRD }}
MCP_BASIC_KEY: ${{ inputs.environment == 'dev' && secrets.MCP_BASIC_KEY_DEV || inputs.environment == 'stg' && secrets.MCP_BASIC_KEY_STG || inputs.environment == 'prd' && secrets.MCP_BASIC_KEY_PRD }}
MCP_PAPERSCORE_KEY: ${{ inputs.environment == 'dev' && secrets.MCP_PAPERSCORE_KEY_DEV || inputs.environment == 'stg' && secrets.MCP_PAPERSCORE_KEY_STG || inputs.environment == 'prd' && secrets.MCP_PAPERSCORE_KEY_PRD }}
XTRAMCP_OPENAI_BASE_URL: ${{ inputs.environment == 'dev' && secrets.XTRAMCP_OPENAI_BASE_URL_DEV || inputs.environment == 'stg' && secrets.XTRAMCP_OPENAI_BASE_URL_STG || inputs.environment == 'prd' && secrets.XTRAMCP_OPENAI_BASE_URL_PRD }}
XTRAMCP_OPENAI_API_KEY: ${{ inputs.environment == 'dev' && secrets.XTRAMCP_OPENAI_API_KEY_DEV || inputs.environment == 'stg' && secrets.XTRAMCP_OPENAI_API_KEY_STG || inputs.environment == 'prd' && secrets.XTRAMCP_OPENAI_API_KEY_PRD }}
XTRAMCP_OPENREVIEW_BASE_URL: ${{ inputs.environment == 'dev' && secrets.XTRAMCP_OPENREVIEW_BASE_URL_DEV || inputs.environment == 'stg' && secrets.XTRAMCP_OPENREVIEW_BASE_URL_STG || inputs.environment == 'prd' && secrets.XTRAMCP_OPENREVIEW_BASE_URL_PRD }}
XTRAMCP_OPENREVIEW_USERNAME: ${{ inputs.environment == 'dev' && secrets.XTRAMCP_OPENREVIEW_USERNAME_DEV || inputs.environment == 'stg' && secrets.XTRAMCP_OPENREVIEW_USERNAME_STG || inputs.environment == 'prd' && secrets.XTRAMCP_OPENREVIEW_USERNAME_PRD }}
XTRAMCP_OPENREVIEW_PASSWORD: ${{ inputs.environment == 'dev' && secrets.XTRAMCP_OPENREVIEW_PASSWORD_DEV || inputs.environment == 'stg' && secrets.XTRAMCP_OPENREVIEW_PASSWORD_STG || inputs.environment == 'prd' && secrets.XTRAMCP_OPENREVIEW_PASSWORD_PRD }}
XTRAMCP_CROSSREF_EMAIL_ADDRESS: ${{ inputs.environment == 'dev' && secrets.XTRAMCP_CROSSREF_EMAIL_ADDRESS_DEV || inputs.environment == 'stg' && secrets.XTRAMCP_CROSSREF_EMAIL_ADDRESS_STG || inputs.environment == 'prd' && secrets.XTRAMCP_CROSSREF_EMAIL_ADDRESS_PRD }}

Copilot uses AI. Check for mistakes.
zip -r dist.zip dist/*

- name: Upload to Chrome Web Store (upload only)
uses: mobilefirstllc/cws-publish@latest
Copy link

Copilot AI Mar 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mobilefirstllc/cws-publish@latest is not pinned, so the workflow can change behavior (or be compromised) without a code change. Pin to a specific release tag or commit SHA for supply-chain safety and reproducibility.

Suggested change
uses: mobilefirstllc/cws-publish@latest
uses: mobilefirstllc/cws-publish@v1

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants