Claude
Skills
Sign in
Back

deploy-to-github

Included with Lifetime
$97 forever

Set up GitHub Actions to deploy this repository via AWS Deployer - creates workflow, updates CloudFormation template with required parameters, and generates parameter files.

Cloud & DevOps

What this skill does


# Set Up GitHub Actions Deployment for AWS Deployer

This skill automatically configures a GitHub repository to deploy via **AWS Deployer** ([github.com/savaki/aws-deployer](https://github.com/savaki/aws-deployer)).

## Prerequisites

- AWS Deployer infrastructure is already set up (use `setup-deployer` skill if not)
- Working directory is a Git repository with a GitHub remote
- Repository has a `cloudformation.template` file (will be created if missing)
- Optional: `S3_ARTIFACT_BUCKET` environment variable set to your artifacts bucket
- Optional: `AWS_REGION` environment variable set to your AWS region

## Your Task

When this skill is invoked, you will **configure** the repository for GitHub Actions deployment by:

1. **Detecting repository information** - Extract repo name from `.git/config`
2. **Getting configuration** - Check environment variables (`S3_ARTIFACT_BUCKET`, `AWS_REGION`) first, ask only if not set
3. **Detecting build system** - Identify build command from project files
4. **Creating/updating GitHub workflow** - Generate `.github/workflows/deploy.yml`
5. **Updating CloudFormation template** - Ensure required parameters exist
6. **Creating parameter files** - Generate base and environment-specific templates
7. **Explaining OIDC setup** - Provide instructions for running `aws-deployer setup-github` and configuring GitHub secrets

**Important**:
- Check environment variables first: `S3_ARTIFACT_BUCKET` and `AWS_REGION`
- Only ask for values if environment variables are not set
- Default AWS region to `us-west-2` if not set
- Do NOT run the `aws-deployer setup-github` command. Explain to the user how to run it.
- Explain that THREE GitHub secrets are required: `AWS_ROLE_ARN`, `S3_ARTIFACT_BUCKET`, and `AWS_REGION`.

## Step 1: Detect Repository Information

Extract the repository owner and name from Git configuration:

```bash
# Get the remote URL
git config --get remote.origin.url
```

Parse the result to extract `owner/repo`:
- `https://github.com/foo/bar.git` → `foo/bar`
- `[email protected]:foo/bar.git` → `foo/bar`

Store as `REPO_FULL_NAME` (e.g., `foo/bar`)

## Step 2: Get Configuration

**S3 Bucket**:
1. Check if `S3_ARTIFACT_BUCKET` environment variable is set
   ```bash
   echo $S3_ARTIFACT_BUCKET
   ```
2. If set, use that value
3. If not set, ask the user for the S3 artifacts bucket name
   - Example: `my-artifacts-bucket`
   - This will be stored as a GitHub secret `S3_ARTIFACT_BUCKET`

**AWS Region**:
1. Check if `AWS_REGION` environment variable is set
   ```bash
   echo $AWS_REGION
   ```
2. If set, use that value
3. If not set, ask the user to confirm the AWS region, providing options:
   - Default: `us-west-2`
   - Other common options: `us-east-1`, `us-east-2`, `eu-west-1`, `ap-southeast-1`
   - Allow custom input

**Initial Environment**: Default to `dev` (don't ask)

## Step 3: Detect Build Command

Check for common build files and infer the build command:

- `Makefile` with `build` target → `make build`
- `package.json` with `build` script → `npm run build`
- `go.mod` → `go build ./...`
- `pom.xml` → `mvn package`
- `build.gradle` → `gradle build`

If multiple or none found, ask the user for the build command.

## Step 4: Create/Update GitHub Workflow

Create `.github/workflows/deploy.yml`:

```yaml
name: Deploy to AWS

on:
  push:
    branches:
      - main
      - develop
  workflow_dispatch:

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: ${{ secrets.AWS_REGION }}

      - name: Set version variables
        id: version
        run: |
          REPO="<repo-owner>/<repo-name>"
          BRANCH="${{ github.ref_name }}"
          SHA_SHORT="${{ github.sha }}"
          SHA_SHORT="${SHA_SHORT:0:6}"
          VERSION="${{ github.run_number }}.${SHA_SHORT}"
          S3_PREFIX="${REPO}/${BRANCH}/${VERSION}"

          echo "repo=${REPO}" >> $GITHUB_OUTPUT
          echo "branch=${BRANCH}" >> $GITHUB_OUTPUT
          echo "version=${VERSION}" >> $GITHUB_OUTPUT
          echo "s3_prefix=${S3_PREFIX}" >> $GITHUB_OUTPUT

      - name: Build application
        run: |
          <build-command>

      - name: Generate CloudFormation parameters
        run: |
          cat > cloudformation-params.json <<EOF
          {
            "Env": "dev",
            "Version": "${{ steps.version.outputs.version }}",
            "S3Bucket": "${{ secrets.S3_ARTIFACT_BUCKET }}",
            "S3Prefix": "${{ steps.version.outputs.s3_prefix }}"
          }
          EOF

      - name: Upload to S3
        run: |
          S3_PATH="s3://${{ secrets.S3_ARTIFACT_BUCKET }}/${{ steps.version.outputs.s3_prefix }}/"

          # Upload CloudFormation template
          aws s3 cp cloudformation.template "${S3_PATH}"

          # Upload parameters
          aws s3 cp cloudformation-params.json "${S3_PATH}"

          # Upload environment-specific parameters if they exist
          if [ -f cloudformation-params.dev.json ]; then
            aws s3 cp cloudformation-params.dev.json "${S3_PATH}"
          fi
          if [ -f cloudformation-params.prd.json ]; then
            aws s3 cp cloudformation-params.prd.json "${S3_PATH}"
          fi

          # Upload any build artifacts as needed
          # Example: aws s3 cp build/function.zip "${S3_PATH}"

      - name: Deployment info
        run: |
          echo "✓ Deployed version: ${{ steps.version.outputs.version }}"
          echo "✓ S3 path: s3://${{ secrets.S3_ARTIFACT_BUCKET }}/${{ steps.version.outputs.s3_prefix }}/"
          echo "✓ Environment: dev"
```

**Replace placeholders**:
- `<repo-owner>/<repo-name>`: Full repository name from Git (e.g., `mycompany/my-app`)
- `<build-command>`: Detected or user-provided build command

**Note**: The workflow uses `${{ secrets.AWS_REGION }}` which will be configured as a GitHub secret.

## Step 5: Update CloudFormation Template

If `cloudformation.template` exists, read it and check for required parameters.

If any of these parameters are missing, add them:

```yaml
Parameters:
  Env:
    Type: String
    Default: dev
    Description: Environment name (dev, staging, prd)
    AllowedValues:
      - dev
      - staging
      - prd

  Version:
    Type: String
    Description: Build version in format {build_number}.{commit_hash}

  S3Bucket:
    Type: String
    Description: Artifacts bucket name

  S3Prefix:
    Type: String
    Description: S3 path to artifacts in format {repo}/{branch}/{version}
```

If `cloudformation.template` doesn't exist, create a simple example:

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: Deployment for <repo-name>

Parameters:
  Env:
    Type: String
    Default: dev
    Description: Environment name (dev, stg, prd, etc)

  Version:
    Type: String
    Description: Build version in format {build_number}.{commit_hash}

  S3Bucket:
    Type: String
    Description: Artifacts bucket name

  S3Prefix:
    Type: String
    Description: S3 path to artifacts in format {repo}/{branch}/{version}

Resources:
  # TODO: Add your infrastructure resources here
  # Example:
  # MyBucket:
  #   Type: AWS::S3::Bucket
  #   Properties:
  #     BucketName: !Sub '${Env}-<repo-name>-${AWS::AccountId}'
  #     Tags:
  #       - Key: Version
  #         Value: !Ref Version
  #       - Key: Environment
  #         Value: !Ref Env
```

**Common usage patterns**:

### Lambda Function
```yaml
MyFunction:
  Type: AWS::Lambda::Function
  Properties:
    FunctionName: !Sub '${Env}-my-function'
    Code:
      S3Bucket: !Ref S3Bucket
      S3Key: !Sub '${S3Prefix}/function.zip'
    Environment:
      Variables:
        VERSION: !Ref Version
```

### ECS Task Definition
```yaml
TaskDefinition:
  Type: AWS::ECS::TaskDefinition
  Properties:
    F

Related in Cloud & DevOps