Skip to content

Fixing issue with referencing non-existent names in tfstate. #10

Fixing issue with referencing non-existent names in tfstate.

Fixing issue with referencing non-existent names in tfstate. #10

Workflow file for this run

name: CI/CD Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
lint:
name: Lint Code
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run ESLint
run: npm run lint
build:
name: Build Docker Images
runs-on: ubuntu-latest
needs: lint
outputs:
tag: ${{ steps.set-outputs.outputs.tag }}
image: ${{ steps.set-outputs.outputs.image }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set outputs
id: set-outputs
run: |
TAG="main-${{ github.sha }}"
IMAGE="ghcr.io/${{ github.repository }}:${TAG}"
echo "tag=${TAG}" >> $GITHUB_OUTPUT
echo "image=${IMAGE}" >> $GITHUB_OUTPUT
echo "Generated tag: ${TAG}"
echo "Generated image: ${IMAGE}"
- name: Build development image
run: docker build --target development -t simple-ci:dev .
- name: Build production image
run: docker build --target production -t simple-ci:prod .
- name: Save images
run: |
docker save simple-ci:dev | gzip > dev-image.tar.gz
docker save simple-ci:prod | gzip > prod-image.tar.gz
- name: Upload dev image artifact
uses: actions/upload-artifact@v4
with:
name: dev-image
path: dev-image.tar.gz
retention-days: 1
- name: Upload prod image artifact
uses: actions/upload-artifact@v4
with:
name: prod-image
path: prod-image.tar.gz
retention-days: 1
test:
name: Test Against Running Production Container
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js for testing
uses: actions/setup-node@v4
with:
node-version: '24'
cache: 'npm'
- name: Install test dependencies
run: npm ci
- name: Run unit tests (isolated)
run: npm test
- name: Download prod image
uses: actions/download-artifact@v4
with:
name: prod-image
- name: Load prod image
run: docker load < prod-image.tar.gz
- name: Start production container
run: |
docker run -d --name test-app -p 3000:3000 simple-ci:prod
sleep 5
- name: Run E2E tests against running container
env:
TEST_BASE_URL: http://localhost:3000
run: npm run test:e2e
- name: Generate test coverage
run: npm run test:coverage
- name: Stop container
if: always()
run: docker stop test-app && docker rm test-app
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: ./coverage/lcov.info
flags: unittests
name: codecov-umbrella
publish:
name: Publish to GitHub Container Registry
runs-on: ubuntu-latest
needs: [build, lint, test]
permissions:
contents: read
packages: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download prod image
uses: actions/download-artifact@v4
with:
name: prod-image
- name: Load prod image
run: docker load < prod-image.tar.gz
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Tag and push image
run: |
# Tag with commit-based tag and latest (if main branch)
docker tag simple-ci:prod ${{ needs.build.outputs.image }}
docker push ${{ needs.build.outputs.image }}
# Also tag as latest if this is the main branch
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
docker tag simple-ci:prod ghcr.io/${{ github.repository }}:latest
docker push ghcr.io/${{ github.repository }}:latest
fi
- name: Output image info
run: |
echo "📦 Published images with commit-based tags:"
echo "${{ needs.build.outputs.image }}"
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
echo "ghcr.io/${{ github.repository }}:latest"
fi
echo ""
echo "🔖 Primary tag: ${{ needs.build.outputs.tag }}"
echo "📌 Commit: ${{ github.sha }}"
echo "👤 Author: ${{ github.event.head_commit.author.name }}"
echo "💬 Message: ${{ github.event.head_commit.message }}"
terraform:
runs-on: ubuntu-latest
needs: [build, publish]
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
- name: Cache Terraform state
uses: actions/cache@v4
with:
path: ./terraform/terraform.tfstate
key: terraform-state-${{ github.ref }}
restore-keys: |
terraform-state-
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: latest
- name: Terraform Init
working-directory: ./terraform
run: terraform init
- name: Terraform Validate
working-directory: ./terraform
run: terraform validate
- name: Remove container from terraform.tfstate
working-directory: ./terraform
run: |
# Check if state file exists and if resources exist in state
if [ -f "terraform.tfstate" ]; then
echo "State file found, checking for existing resources..."
# Remove namespace if it exists in state
if terraform state list | grep -q "nexaa_namespace.simple-ci"; then
echo "Namespace resource found in state, removing..."
terraform state rm nexaa_namespace.simple-ci
else
echo "Namespace resource not found in state, skipping removal"
fi
# Remove container if it exists in state
if terraform state list | grep -q "nexaa_container.simple-ci"; then
echo "Container resource found in state, removing..."
terraform state rm nexaa_container.simple-ci
else
echo "Container resource not found in state, skipping removal"
fi
else
echo "No state file found, skipping removal"
fi
env:
TF_VAR_nexaa_username: ${{ secrets.NEXAA_USERNAME }}
TF_VAR_nexaa_password: ${{ secrets.NEXAA_PASSWORD }}
- name: Terraform Import
working-directory: ./terraform
run: |
# Try to import the namespace resource first
echo "Attempting to import namespace resource..."
if terraform import nexaa_namespace.simple-ci simple-ci; then
echo "✅ Namespace resource imported successfully"
else
echo "⚠️ Namespace resource import failed (resource may not exist remotely)"
echo "This is normal for first deployments or if the namespace was deleted"
echo "Terraform will create the resource during apply"
fi
# Try to import the container resource
echo "Attempting to import container resource..."
if terraform import nexaa_container.simple-ci simple-ci/simple-ci; then
echo "✅ Container resource imported successfully"
else
echo "⚠️ Container resource import failed (resource may not exist remotely)"
echo "This is normal for first deployments or if the container was deleted"
echo "Terraform will create the resource during apply"
fi
env:
TF_VAR_nexaa_username: ${{ secrets.NEXAA_USERNAME }}
TF_VAR_nexaa_password: ${{ secrets.NEXAA_PASSWORD }}
- name: Terraform Plan
working-directory: ./terraform
run: terraform plan
env:
TF_VAR_nexaa_username: ${{ secrets.NEXAA_USERNAME }}
TF_VAR_nexaa_password: ${{ secrets.NEXAA_PASSWORD }}
- name: Terraform Apply
working-directory: ./terraform
run: terraform apply -auto-approve
env:
TF_VAR_nexaa_username: ${{ secrets.NEXAA_USERNAME }}
TF_VAR_nexaa_password: ${{ secrets.NEXAA_PASSWORD }}
TF_VAR_container_image: ${{ needs.build.outputs.image }}