Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ca6fed4
Add grace period to jobs to deter disruption (#10)
wjossey Jun 18, 2025
d896fe7
Add codeowners (#11)
vmelikyan Jun 18, 2025
4ec1365
feat: init tilt setup (#12)
vigneshrajsb Jun 19, 2025
f182580
doc: init local dev docs (#13)
vigneshrajsb Jun 19, 2025
3906820
update release pipeline to support pre-releases (#14)
vmelikyan Jun 21, 2025
00d90fc
chore: fix security vulnerabilities, updates husky hook (#15)
vigneshrajsb Jun 27, 2025
ae00185
Native build and helm support (#16)
vmelikyan Jun 27, 2025
6bffaf7
feat: configurable labels (#17)
vigneshrajsb Jun 30, 2025
1195c8a
Bump the npm_and_yarn group across 1 directory with 19 updates
dependabot[bot] Jul 2, 2025
5d8bd2c
feat: docker and command type for webhooks (#18)
vigneshrajsb Jul 7, 2025
03e5bb6
Merge branch 'main' into merge-main-into-main-ud
nickhodaly-ud Jul 8, 2025
ca657d0
fix lint errors
nickhodaly-ud Jul 8, 2025
472aba1
chore: fix typo on readme (#20)
stevejcox Jul 10, 2025
970f2a9
feat: adding more v1 apis (#19)
vigneshrajsb Jul 10, 2025
00f3802
fixes resource character limit for k8s apply (#21)
vmelikyan Jul 11, 2025
0420ce7
Merge branch 'main' into merge-main-into-main-ud
nickhodaly-ud Jul 11, 2025
3e9cfd0
Removes job deadline for k8s deploy jobs (#22)
vmelikyan Jul 11, 2025
4698957
Merge branch 'main' into merge-main-into-main-ud
nickhodaly-ud Jul 11, 2025
dcbf5a3
Db config breakup (#23)
vmelikyan Jul 11, 2025
f58b84e
fix: temp fix for job name creation (#24)
vigneshrajsb Jul 11, 2025
e28fa0e
Merge pull request #11 from Underdog-Inc/dependabot/npm_and_yarn/npm_…
t3ntman Jul 16, 2025
d7d61f7
feat: flag for mission control comments (#27)
vigneshrajsb Jul 21, 2025
87016e1
Merge branch 'main-ud' into merge-main-into-main-ud
nickhodaly-ud Jul 24, 2025
07afeea
Merge branch 'GoodRxOSS:main' into main
nickhodaly-ud Jul 24, 2025
1ea7f6c
Merge branch 'main' into merge-main-into-main-ud
nickhodaly-ud Jul 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .env.ci
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
DATABASE_URL=postgresql://root:root@localhost:5432/lifecycle
APP_DB_HOST=localhost
APP_DB_PORT=5432
APP_DB_USER=root
APP_DB_PASSWORD=root
APP_DB_NAME=lifecycle
APP_DB_SSL=false
REDIS_URL=redis://localhost:6379
APP_REDIS_HOST=localhost
APP_REDIS_PORT=6379
APP_REDIS_PASSWORD=
APP_REDIS_TLS=false
GITHUB_WEBHOOK_SECRET='o1o1o1o1'
CODEFRESH_API_KEY='o1o1o1o1o1'
GITHUB_PRIVATE_KEY='o1o1o1o1o1'
Expand Down
25 changes: 20 additions & 5 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
# DATABASE CONFIGURATION
# Option 1: Individual database variables (recommended)
APP_DB_HOST='localhost'
APP_DB_PORT='5434'
APP_DB_USER='lifecycle'
APP_DB_PASSWORD='lifecycle'
APP_DB_NAME='lifecycle'
APP_DB_SSL='false'

# Option 2: Legacy DATABASE_URL format (for backward compatibility)
# DEPRECATED: This format will be removed in future releases. Please use individual APP_DB_* variables above.
# You need the production db password below
# DATABASE_URL='postgresql://lifecycle:<password>@localhost:5432/lifecycle'
# You may need to update the port
DATABASE_URL='postgresql://lifecycle:lifecycle@localhost:5434/lifecycle'
DATABASE_HOST='localhost'
DATABASE_NAME='lifecycle'
DATABASE_PASSWORD='lifecycle'

# REDIS
# REDIS CONFIGURATION
# Option 1: Individual Redis variables (recommended)
APP_REDIS_HOST='localhost'
APP_REDIS_PORT='6379'
APP_REDIS_PASSWORD=''
APP_REDIS_TLS='false'

# Option 2: Legacy REDIS_URL format (for backward compatibility)
# DEPRECATED: This format will be removed in future releases. Please use individual APP_REDIS_* variables above.
REDIS_URL='redis://localhost:6379'
REDIS_PORT='6379'

# GITHUB
# This is all created while you're creating your GitHub App and Test repository
Expand Down
62 changes: 58 additions & 4 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build & Push Docker Images on ReleaseAdd commentMore actions
name: Build & Push Docker Images on Release

on:
release:
Expand All @@ -10,29 +10,83 @@ jobs:
steps:
- name: Check out repository
uses: actions/checkout@v3

- name: Extract release metadata
id: meta
run: |
# Get the tag name
VERSION="${GITHUB_REF_NAME}"
echo "version=$VERSION" >> $GITHUB_OUTPUT

# Check if this is a pre-release
if [[ "${{ github.event.release.prerelease }}" == "true" ]]; then
echo "is_prerelease=true" >> $GITHUB_OUTPUT

# Extract pre-release type (beta, alpha, rc, etc.)
if [[ "$VERSION" =~ -([a-zA-Z]+)\. ]]; then
PRERELEASE_TYPE="${BASH_REMATCH[1]}"
echo "prerelease_type=$PRERELEASE_TYPE" >> $GITHUB_OUTPUT
else
echo "prerelease_type=beta" >> $GITHUB_OUTPUT
fi
else
echo "is_prerelease=false" >> $GITHUB_OUTPUT
fi

# Output for debugging
echo "Version: $VERSION"
echo "Is Pre-release: ${{ github.event.release.prerelease }}"

- name: Set up QEMU (for multi-arch)
uses: docker/setup-qemu-action@v3
with:
platforms: all

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
buildkitd-flags: --debug

- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Determine Docker tags
id: tags
run: |
TAGS="${{ secrets.DOCKERHUB_USERNAME }}/app:${{ steps.meta.outputs.version }}"

if [[ "${{ steps.meta.outputs.is_prerelease }}" == "true" ]]; then
# For pre-releases, add the pre-release type tag (beta, alpha, rc, etc.)
TAGS="$TAGS,${{ secrets.DOCKERHUB_USERNAME }}/app:${{ steps.meta.outputs.prerelease_type }}"
else
# For stable releases, add the 'latest' tag
TAGS="$TAGS,${{ secrets.DOCKERHUB_USERNAME }}/app:latest"

# Also add major and major.minor tags for stable releases
# e.g., 1.2.3 -> also tag as 1 and 1.2
VERSION="${{ steps.meta.outputs.version }}"
if [[ "$VERSION" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
MAJOR="${BASH_REMATCH[1]}"
MINOR="${BASH_REMATCH[2]}"
TAGS="$TAGS,${{ secrets.DOCKERHUB_USERNAME }}/app:$MAJOR"
TAGS="$TAGS,${{ secrets.DOCKERHUB_USERNAME }}/app:$MAJOR.$MINOR"
fi
fi

echo "tags=$TAGS" >> $GITHUB_OUTPUT
echo "Docker tags: $TAGS"

- name: Build and push lifecycle image
uses: docker/build-push-action@v4
with:
context: .
file: Dockerfile
push: true
platforms: linux/amd64,linux/arm64
tags: |
${{ secrets.DOCKERHUB_USERNAME }}/app:${{ github.ref_name }}
${{ secrets.DOCKERHUB_USERNAME }}/app:latest
tags: ${{ steps.tags.outputs.tags }}
build-args: |
PORT=5001
NODE_ENV=production
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,9 @@ dist

helm/environments/**/secrets.yaml

# Claude Code files
CLAUDE.md
llm-docs/
llm-specs/

.tool-versions
5 changes: 5 additions & 0 deletions .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# Husky will pass the path to the temporary commit‐message file as $1
npx commitlint --edit "$1"
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged && npx commitlint --edit $1
npx lint-staged
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Ignore Helm templates
helm/**/templates/*.yaml
helm/**/templates/*.yml
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @GoodRxOSS/lifecycle-core
63 changes: 62 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ lifecycle is a tool that transforms pull requests into ephemeral development env
Isolated environments for feature branches to develop, without interference from others' work.

- **Testing:**
Fully connected and function environments for manula and automated testing.
Fully connected and function environments for manual and automated testing.

- **Design Review:**
Live environments for product managers and designers to interact with new features.
Expand All @@ -28,3 +28,64 @@ lifecycle is a tool that transforms pull requests into ephemeral development env
Isolated sandboxes for partners and vendors that share only what’s necessary, avoiding full staging access.

Happy coding! Join the community on [Discord](https://discord.gg/TEtKgCs8T8)


## Development

### Prerequisites

Install the following tools using [Homebrew](https://brew.sh/):

```shell
brew install tilt kind kubectx kubectl
brew install --cask docker
```

### Configuration

- **Ngrok**:
The project uses `ngrok` to create a public URL for your local instance. You will need to:
- Sign up for an [ngrok account](https://dashboard.ngrok.com/signup) to get an authtoken.
- Set the following environment variables. You can add them to your shell profile (e.g., `~/.zshrc` or `~/.bash_profile`).

```shell
export NGROK_AUTHTOKEN="<your_ngrok_authtoken>"
export NGROK_LIFECYCLE_DOMAIN="<your_ngrok_domain>" # your ngrok domain. needs paid plan to get a static domain
```

- **AWS Credentials**: (Optional, if using AWS ECR)
Ensure your AWS credentials are set up in `~/.aws/credentials`. The Tilt environment needs this to create a Kubernetes secret for the application.

### Running Locally

- Create a local Kubernetes cluster using `kind`:
```shell
kind create cluster --config sysops/tilt/kind-config.yaml --name lfc
```
> [!IMPORTANT]
> We need to use a custom `kind` config file to allow insecure registries setup for local development.

- Switch your Kubernetes context to the newly created cluster:
```shell
kx kind-lfc
```

- Setup local env secrets at `helm/environments/local/secrets.yaml`:
```yaml
secrets:
databaseUrl: postgresql://lifecycle:lifecycle@local-postgres:5432/lifecycle
redisUrl: redis://redis-master:6379
githubPrivateKey: "<private_key_without_new_lines>"
githubClientSecret: "<client_secret>"
githubWebhookSecret: "<webhook_secret>"
githubAppId: "<app_id>"
githubClientId: "<client_id>"
githubInstallationId: "<installation_id>"
```
> [!NOTE]
> You can create the GitHub app with the app creation setup flow and then copy the secrets created for local development.

- Start the development environment using `tilt`:
```shell
tilt up
```
40 changes: 28 additions & 12 deletions Tiltfile
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,15 @@ docker_build_with_restart(
entrypoint=["/app_setup_entrypoint.sh"],
dockerfile="sysops/dockerfiles/tilt.app.dockerfile",
build_args={
"DATABASE_URL": "postgresql://lifecycle:lifecycle@local-postgres.{}.svc.cluster.local:5432/lifecycle".format(app_namespace),
"REDIS_URL": "redis://redis-master.{}.svc.cluster.local:6379".format(app_namespace),
"APP_DB_HOST": "local-postgres.{}.svc.cluster.local".format(app_namespace),
"APP_DB_PORT": "5432",
"APP_DB_USER": "lifecycle",
"APP_DB_PASSWORD": "lifecycle",
"APP_DB_NAME": "lifecycle",
"APP_DB_SSL": "false",
"APP_REDIS_HOST": "redis-master.{}.svc.cluster.local".format(app_namespace),
"APP_REDIS_PORT": "6379",
"APP_REDIS_PASSWORD": "",
},
live_update=[
sync("./src", "/app/src"),
Expand Down Expand Up @@ -192,14 +199,23 @@ k8s_resource(
labels=["infra"]
)

# Helper function to add namespace to kubernetes resources
def kustomize_with_helm(yaml_path, namespace):
yaml = helm(
None,
name="custom-namespace",
namespace=namespace,
template=[yaml_path],
set=["namespace={}".format(namespace)]
)
return yaml
##################################
# DISTRIBUTION
##################################
k8s_yaml('sysops/tilt/distribution.yaml')
k8s_resource(
'distribution',
port_forwards=["8088:5000"],
labels=["infra"]
)

##################################
# BUILDKIT
##################################
k8s_yaml('sysops/tilt/buildkit.yaml')
k8s_resource(
'buildkit',
port_forwards=["1234:1234"],
resource_deps=['distribution'],
labels=["infra"]
)
Loading