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
8 changes: 8 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: 2
updates:
- package-ecosystem: github-actions
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
directory: /
schedule:
interval: monthly
cooldown:
default-days: 7
22 changes: 11 additions & 11 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,35 @@ name: CD
on:
workflow_call:
jobs:
deploy:
deploy: # zizmor: ignore[secrets-outside-env] reusable workflow; environments are managed by callers
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- name: Tag and Push Gem
id: tag-and-push-gem
uses: discourse/publish-rubygems-action@v3
uses: discourse/publish-rubygems-action@4bd305c65315cb691bad1e8de97a87aaf29a0a85 # v3
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
GIT_EMAIL: ${{secrets.GUSTO_GIT_EMAIL}}
GIT_NAME: ${{secrets.GUSTO_GIT_NAME}}
RUBYGEMS_API_KEY: ${{secrets.RUBYGEMS_API_KEY}}
- name: Create GitHub Release
# zizmor: ignore[template-injection] gem_version comes from a trusted prior step
run: gh release create v${{steps.tag-and-push-gem.outputs.gem_version}} --generate-notes
if: ${{ steps.tag-and-push-gem.outputs.new_version == 'true' }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
notify_on_failure:
notify_on_failure: # zizmor: ignore[secrets-outside-env] reusable workflow; environments are managed by callers
runs-on: ubuntu-latest
needs: [deploy]
if: ${{ failure() && github.ref == 'refs/heads/main' }}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
steps:
- uses: slackapi/slack-github-action@v1.25.0
- uses: slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95 # v3
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook
payload: |
{
"text": "${{ github.repository }}/${{ github.ref }}: FAILED\n${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}
text: "${{ github.repository }}/${{ github.ref }}: FAILED\n${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
33 changes: 19 additions & 14 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,28 @@ jobs:
BUNDLE_GEMFILE: Gemfile
name: "Run tests: Ruby ${{ matrix.ruby }}"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- name: Install ripgrep
run: sudo apt-get install -y ripgrep
- name: Set up Ruby ${{ matrix.ruby }}
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1
with:
bundler-cache: true
ruby-version: ${{ matrix.ruby }}
- name: Run tests
# zizmor: ignore[template-injection] workflow_call inputs are controlled by the caller
run: ${{ inputs.test-command }}
static_type_check:
name: "Type Check"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- name: Set up Ruby
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1
with:
bundler-cache: true
ruby-version: 3.4
Expand All @@ -53,25 +58,25 @@ jobs:
runs-on: ubuntu-latest
name: "Linter"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- name: Set up Ruby
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1
with:
bundler-cache: true
ruby-version: 3.4
- name: Run linter
# zizmor: ignore[template-injection] workflow_call inputs are controlled by the caller
run: ${{ inputs.linter-command }}
notify_on_failure:
notify_on_failure: # zizmor: ignore[secrets-outside-env] reusable workflow; environments are managed by callers
runs-on: ubuntu-latest
needs: [run_tests, static_type_check, run_linter]
if: ${{ failure() && github.ref == 'refs/heads/main' }}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
steps:
- uses: slackapi/slack-github-action@v1.25.0
- uses: slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95 # v3
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook
payload: |
{
"text": "${{ github.repository }}/${{ github.ref }}: FAILED\n${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}
text: "${{ github.repository }}/${{ github.ref }}: FAILED\n${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
2 changes: 1 addition & 1 deletion .github/workflows/stale.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
- uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10
with:
stale-issue-message: 'This issue has been marked stale because it has been open for six months with no activity. To prevent this issue from automatically being closed in one week, update it or remove the stale label.'
stale-pr-message: 'This PR has been marked stale because it has been open for six months with no activity. To prevent this PR from automatically being closed in one week, update it or remove the stale label.'
Expand Down
23 changes: 23 additions & 0 deletions .github/workflows/zizmor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: GitHub Actions Security Analysis

on:
push:
branches: [main]
pull_request:
branches: ["**"]

permissions: {}

jobs:
zizmor:
runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
actions: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- name: Run zizmor
uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3
62 changes: 61 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,61 @@
# shared-config
# shared-config

Shared reusable GitHub Actions workflows for [rubyatscale](https://github.com/rubyatscale) gems.

## Workflows

### Reusable workflows (`workflow_call`)

These workflows are called from individual gem repos via `uses: rubyatscale/shared-config/.github/workflows/<name>.yml@main`.

| Workflow | Description |
|----------|-------------|
| **CI** (`ci.yml`) | Runs tests across Ruby 3.2–4.0, Sorbet type checking, and linting (RuboCop). Test and linter commands are configurable via inputs. |
| **CD** (`cd.yml`) | Publishes the gem to RubyGems and creates a GitHub Release on successful main builds. |
| **Stale** (`stale.yml`) | Marks issues and PRs as stale after 180 days of inactivity, then closes them after 7 more days. |
| **Triage** (`triage.yml`) | Labels new issues with `triage`. |

### Repository workflows

| Workflow | Description |
|----------|-------------|
| **zizmor** (`zizmor.yml`) | Runs the [zizmor](https://github.com/zizmorcore/zizmor) security linter against all workflow files on every push and PR. |

## Usage

In a gem repo, create a workflow that calls the shared workflow:

```yaml
# .github/workflows/ci.yml
name: CI

on:
push:
branches: [main]
pull_request:

jobs:
ci:
uses: rubyatscale/shared-config/.github/workflows/ci.yml@main
```

### CI inputs

| Input | Default | Description |
|-------|---------|-------------|
| `test-command` | `bundle exec rspec` | Command to run tests |
| `linter-command` | `bundle exec rubocop` | Command to run the linter |

### Required secrets

The **CD** workflow requires the following secrets in the calling repo:

- `GUSTO_GIT_EMAIL` / `GUSTO_GIT_NAME` — Git identity for tagging
- `RUBYGEMS_API_KEY` — API key for publishing to RubyGems
- `SLACK_WEBHOOK_URL` — Incoming webhook URL for failure notifications (used by both CI and CD)

## Security

- All action references are pinned to SHA hashes
- [zizmor](https://github.com/zizmorcore/zizmor) runs on every PR to lint workflows for security issues
- [Dependabot](https://docs.github.com/en/code-security/dependabot) is configured for monthly GitHub Actions updates