Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
89 changes: 89 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ on:
permissions:
contents: read
id-token: write # Required for OIDC authentication
deployments: write # Required for creating deployments

jobs:
deploy:
Expand Down Expand Up @@ -56,6 +57,40 @@ jobs:
aws-region: us-east-1
role-session-name: Deploy-${{ github.event.repository.name }}-${{ github.run_id }}

- name: Create GitHub Deployment (Staging)
if: github.ref == 'refs/heads/staging'
id: deployment_staging
uses: actions/github-script@v7
with:
script: |
const deployment = await github.rest.repos.createDeployment({
owner: context.repo.owner,
repo: context.repo.repo,
ref: context.sha,
environment: 'staging',
description: `Deploy staging site to S3`,
auto_merge: false,
required_contexts: []
});
return deployment.data.id;

- name: Create GitHub Deployment (Production)
if: github.ref == 'refs/heads/main'
id: deployment_production
uses: actions/github-script@v7
with:
script: |
const deployment = await github.rest.repos.createDeployment({
owner: context.repo.owner,
repo: context.repo.repo,
ref: context.sha,
environment: 'production',
description: `Deploy production site to S3 and CloudFront`,
auto_merge: false,
required_contexts: []
});
return deployment.data.id;

- name: Deploy to S3 (Staging)
if: github.ref == 'refs/heads/staging'
run: |
Expand All @@ -76,3 +111,57 @@ jobs:
aws cloudfront create-invalidation \
--distribution-id ${{ steps.config.outputs.cloudfront }} \
--paths "/*"

- name: Update Deployment Status (Staging Success)
if: github.ref == 'refs/heads/staging' && success()
uses: actions/github-script@v7
with:
script: |
await github.rest.repos.createDeploymentStatus({
owner: context.repo.owner,
repo: context.repo.repo,
deployment_id: ${{ steps.deployment_staging.outputs.result }},
state: 'success',
Comment on lines +121 to +124
Copy link

Copilot AI Mar 8, 2026

Choose a reason for hiding this comment

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

The step IDs deployment-staging / deployment-production contain hyphens, but later they’re referenced with dot-notation (steps.deployment-staging...). In GitHub Actions expressions, IDs with - must be accessed with bracket syntax (e.g. steps['deployment-staging'].outputs.result) or renamed to use _. As written, deployment_id will not resolve correctly and the status update will fail.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback, this feedback, this feedback, which are all pretty much the same issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit 8e0f17b:

Step IDs: Changed from deployment-staging/deployment-production to deployment_staging/deployment_production (using underscores instead of hyphens). This allows proper dot-notation access in GitHub Actions expressions.

README links: Changed from relative ../../deployments to absolute https://github.com/OpenNews/srccon/deployments to ensure the links work correctly from any viewing context.

All references throughout the workflow have been updated to use the new step IDs.

environment_url: 'http://${{ steps.config.outputs.staging_bucket }}.s3-website-us-east-1.amazonaws.com',
description: 'Staging deployment completed successfully'
});

- name: Update Deployment Status (Production Success)
if: github.ref == 'refs/heads/main' && success()
uses: actions/github-script@v7
with:
script: |
await github.rest.repos.createDeploymentStatus({
owner: context.repo.owner,
repo: context.repo.repo,
deployment_id: ${{ steps.deployment_production.outputs.result }},
state: 'success',
environment_url: 'https://srccon.org',
description: 'Production deployment completed successfully'
});

- name: Update Deployment Status (Staging Failure)
if: github.ref == 'refs/heads/staging' && failure() && steps.deployment_staging.outputs.result
uses: actions/github-script@v7
with:
script: |
await github.rest.repos.createDeploymentStatus({
owner: context.repo.owner,
repo: context.repo.repo,
deployment_id: ${{ steps.deployment_staging.outputs.result }},
state: 'failure',
description: 'Staging deployment failed'
});

- name: Update Deployment Status (Production Failure)
if: github.ref == 'refs/heads/main' && failure() && steps.deployment_production.outputs.result
uses: actions/github-script@v7
with:
script: |
await github.rest.repos.createDeploymentStatus({
owner: context.repo.owner,
repo: context.repo.repo,
deployment_id: ${{ steps.deployment_production.outputs.result }},
state: 'failure',
description: 'Production deployment failed'
});
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,18 +110,22 @@ This project uses GitHub Actions for automated deployment to AWS S3 and CloudFro
- `staging` → Staging deployment (S3 only)
- Other branches → Test builds only (no deployment)

All deployments are tracked in GitHub's **Deployments** tab, making it easy to see deployment history, status, and environment URLs.

### Pushing to staging

- When you're ready to have someone review a site update, update the `staging` branch in GitHub. If you're working in `staging` locally, you just need to push your code changes. If you're working in a separate feature branch, push that branch to GitHub and then open a pull request into `staging` and merge it.
- A commit to the `staging` branch on GitHub will trigger an automatic build of the SRCCON staging site via GitHub Actions.
- The GitHub Actions workflow can take a minute or two to complete. Your changes will not be visible on the staging site immediately, but they'll be there quickly.
- **View deployment status:** Check the repository's [Deployments](https://github.com/OpenNews/srccon/deployments) tab to see the deployment history and status.

### Pushing to production

- Review your changes on the staging site, and if everything looks OK, come back to this repo and open a pull request from `staging` into `main`.
- **Optional QA step:** Run `bundle exec rake review:compare_deployed_sites` to see a detailed comparison of staging vs production content before merging.
- Merging a pull request into `main`, or pushing any commit to the `main` branch, will trigger an automatic build of the production site at [srccon.org](https://srccon.org) via GitHub Actions.
- The production site is delivered through Amazon CloudFront so that we can serve a secure, https-enabled [srccon.org](https://srccon.org). CloudFront also caches everything for performance. The rebuild process triggers an invalidation of the entire cache, but it still may take up to 10 minutes for site changes to be reflected on production.
- **View deployment status:** Check the repository's [Deployments](https://github.com/OpenNews/srccon/deployments) tab to see the deployment history and status.

### GitHub Actions Workflows

Expand All @@ -130,9 +134,10 @@ The repository includes GitHub Actions workflows in `.github/workflows/`:
1. **Deploy Workflow** (`deploy.yml`)
- Triggers on push to `main` or `staging` branches
- Builds Jekyll site with Ruby 3.2
- Creates GitHub Deployment events for tracking
- Deploys to S3 using AWS CLI with OIDC authentication
- Invalidates CloudFront cache (production only)
- Sends Slack notifications on completion
- Updates deployment status (success/failure) in GitHub Deployments tab

2. **Test Workflow** (`test.yml`)
- Runs on all PRs and non-deployment branches
Expand Down