Skip to content

Commit 329c609

Browse files
authored
Merge pull request #1 from github/init
Init
2 parents b5a3533 + 29b8774 commit 329c609

File tree

106 files changed

+1621
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+1621
-0
lines changed

.bundle/config

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
BUNDLE_BIN: "bin"
3+
BUNDLE_PATH: "vendor/gems"
4+
BUNDLE_CACHE_PATH: "vendor/cache"
5+
BUNDLE_CACHE_ALL: "true"
6+
BUNDLE_SPECIFIC_PLATFORM: "true"
7+
BUNDLE_NO_INSTALL: "true"

.dockerignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
docs/
2+
bin/
3+
README.md
4+
.gitignore
5+
tmp/
6+
.git
7+
coverage/
8+
vendor/gems/
9+
.github/
10+
.devcontainer/
11+
.ruby-lsp/
12+
docker-compose.yml

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* @GrantBirki

.github/copilot-instructions.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Copilot Instructions
2+
3+
You are an AI assistant that specializes in software development for the Ruby programming language.
4+
5+
## Environment Setup
6+
7+
Regarding scripts that manage the environment or start the app, follow the guidance given by GitHub in their [Scripts to Rule Them All](https://github.blog/engineering/scripts-to-rule-them-all/) blog post. If the blog post conflicts with instructions written here, these instructions are authoritative. For example:
8+
9+
Bootstrap the Ruby project by running:
10+
11+
```bash
12+
script/bootstrap
13+
```
14+
15+
## Testing
16+
17+
Ensure all unit tests pass by running the following:
18+
19+
```bash
20+
script/test
21+
```
22+
23+
This project **requires 100% test coverage** of code, not including:
24+
25+
- dependencies or their bin scripts
26+
- tests
27+
- scripts in `script/`
28+
- contents of directories that begin with a dot (`.`)
29+
30+
Tests are powered by Ruby's `rspec`. By running `script/test`, the tool `simplecov` will be automatically used and will exit with a non-zero code if the coverage is below 100%.
31+
32+
## Linting
33+
34+
Ensure the linter passes by running:
35+
36+
```bash
37+
script/lint
38+
```
39+
40+
The linter is powered by `rubocop` with its config file located at `.rubocop.yml`. The linter will exit with a non-zero code if any issues are found. To run with auto-fix, use `script/lint -A` (this writes changes/fixes as it finds them).
41+
42+
## Project Guidelines
43+
44+
- Follow:
45+
- Object-Oriented best practices, especially abstraction and encapsulation
46+
- GRASP Principles, especially Information Expert, Creator, Indirection, Low Coupling, High Cohesion, and Pure Fabrication
47+
- SOLID principles, especially Dependency Inversion, Open/Closed, and Single Responsibility
48+
- Design Patterns defined by the Gang of Four, especially Abstract Factory, Factory Method, Chain of Responsibility, Command, Mediator, Observer, State, and Adaptor patterns.
49+
- The YAGI rule: do not introduce extra indirection, abstraction, or complexity unless the benefits of doing so are immediately used. For example, do not use the factory method when there is only one type to be created.
50+
- Use double quotes for strings unless single quotes are absolutely required.
51+
- Base new work on latest `main` branch.
52+
- Changes should maintain consistency with existing patterns and style.
53+
- Document changes clearly and thoroughly, including updates to existing comments when appropriate. Try to use the same "voice" as the other comments, mimicking their tone and style.
54+
- When responding to code refactoring suggestions, function suggestions, or other code changes, please keep your responses as concise as possible. We are capable engineers and can understand the code changes without excessive explanation. If you feel that a more detailed explanation is necessary, you can provide it, but keep it concise.
55+
- When suggesting code changes, always opt for the most maintainable approach. Try your best to keep the code clean and follow DRY principles. Avoid unnecessary complexity and always consider the long-term maintainability of the code.
56+
- When writing unit tests, try to consider edge cases as well as the main path of success. This will help ensure that the code is robust and can handle unexpected inputs or situations.
57+
- If you are updating docs to be YARD-style, please ensure that you keep all and any existing notes or examples in the documentation. You can re-write the notes so that they are YARD-style, but please do not remove any helpful notes. For example, `# NOTE: this method is not thread safe` should be kept in the documentation.
58+
- No additions should ever include credentials, secrets, or personally-identifying information (except github.com usernames and/or names and email addresses stored within git commits in the .git directory).
59+
- Hard-coded strings should almost always be constant variables.
60+
- In general, avoid introducing new dependencies. Use the following guidance:
61+
- Some dependencies are the de facto way to accomplish a goal and should be introduced. For example:
62+
- using a dependency to connect to a database, such as mysql2
63+
- using a dependency for instrumentation, such as dogstatsd-ruby
64+
- using a dependency for process management, such as puma
65+
- using a dependency for unit testing, such as rspec
66+
- using a dependency for serving HTTP requests, such as sinatra
67+
- Introducing a dependency to only use a single method from it should be avoided. Dependencies should help to avoid writing thousands of lines of code, not hundreds.
68+
- Introducing a dependency to use it for a different purpose than it was written for should be avoided
69+
- In writing code, take the following as preferences but not rules:
70+
- Understandability over concision
71+
- Syntax, expressions, and blocks that are common across many languages over language-specific syntax.
72+
- More descriptive names over brevity of variable, function, and class names.
73+
- The use of whitespace (newlines) over compactness of files.
74+
- Naming of variables and methods that lead to expressions and blocks reading more like English sentences.
75+
- Less lines of code over more. Keep changes minimal and focused.
76+
77+
## Pull Request Requirements
78+
79+
- All tests must pass.
80+
- The linter must pass.
81+
- Documentation must be up-to-date.
82+
- Any new dependencies must be vendored.
83+
- All new code must have YARD-style documentation.
84+
- The body of the Pull Request should:
85+
- Contain a summary of the changes.
86+
- Make special note of any changes to dependencies.
87+
- Comment on the security of the changes being made and offer suggestions for further securing the code.
88+
89+
## Repository Organization
90+
91+
- `.github/` - GitHub configurations and settings
92+
- `docs/` - Main documentation storage
93+
- `script/` - Repository maintenance scripts. Includes things like `script/bootstrap`, `script/test`, and `script/lint`.
94+
- `config/` - Configuration files for the project.
95+
- `lib/` - Main code for the project. This is where the main application/service code lives.
96+
- `spec/` - Tests for the project. This is where the unit tests and acceptance tests live.
97+
- `vendor/cache` - Vendored dependencies (Ruby Gems).
98+
- `vendor/gems` - Location to which bundler should install the Ruby Gems sourced from `vendor/cache`.

.github/dependabot.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
version: 2
3+
updates:
4+
- package-ecosystem: bundler
5+
vendor: true
6+
directory: "/"
7+
schedule:
8+
interval: weekly
9+
day: "monday"
10+
time: "21:00"
11+
groups:
12+
prod-ruby-dependencies:
13+
dependency-type: "production"
14+
patterns:
15+
- "*"
16+
dev-ruby-dependencies:
17+
dependency-type: "development"
18+
patterns:
19+
- "*"
20+
- package-ecosystem: github-actions
21+
directory: "/"
22+
groups:
23+
github-actions:
24+
patterns:
25+
- "*"
26+
schedule:
27+
interval: weekly
28+
day: "tuesday"
29+
time: "21:00"

.github/workflows/build.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: build
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
build:
16+
name: build
17+
18+
strategy:
19+
matrix:
20+
os: [ubuntu-latest, macos-latest]
21+
runs-on: ${{ matrix.os }}
22+
23+
steps:
24+
- name: checkout
25+
uses: actions/checkout@v4
26+
27+
- uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # [email protected]
28+
with:
29+
bundler-cache: true
30+
31+
- name: bootstrap
32+
run: script/bootstrap
33+
34+
- name: build
35+
run: script/build
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: "Copilot Setup Steps"
2+
3+
# Allows you to test the setup steps from your repository's "Actions" tab
4+
on: workflow_dispatch
5+
6+
jobs:
7+
copilot-setup-steps:
8+
runs-on: ubuntu-latest
9+
# Set the permissions to the lowest permissions possible needed for *your steps*. Copilot will be given its own token for its operations.
10+
permissions:
11+
# If you want to clone the repository as part of your setup steps, for example to install dependencies, you'll need the `contents: read` permission. If you don't clone the repository in your setup steps, Copilot will do this for you automatically after the steps complete.
12+
contents: read
13+
steps:
14+
- name: checkout
15+
uses: actions/checkout@v4
16+
17+
- uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # [email protected]
18+
with:
19+
bundler-cache: true
20+
21+
- name: bootstrap
22+
run: script/bootstrap

.github/workflows/lint.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: lint
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
lint:
14+
name: lint
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: checkout
19+
uses: actions/checkout@v4
20+
21+
- uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # [email protected]
22+
with:
23+
bundler-cache: true
24+
25+
- name: bootstrap
26+
run: script/bootstrap
27+
28+
- name: lint
29+
run: script/lint

.github/workflows/release.yml

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
name: release
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
branches:
7+
- main
8+
paths:
9+
- lib/hooks/version.rb
10+
11+
permissions: {}
12+
13+
jobs:
14+
build:
15+
if: github.repository == 'github/hooks'
16+
permissions:
17+
contents: read
18+
runs-on: ubuntu-latest
19+
outputs:
20+
artifact-id: ${{ steps.upload-artifact.outputs.artifact-id }}
21+
gem_name: ${{ steps.build.outputs.gem_name }}
22+
gem_version: ${{ steps.build.outputs.gem_version }}
23+
gem_path: ${{ steps.build.outputs.gem_path }}
24+
25+
steps:
26+
- name: checkout
27+
uses: actions/checkout@v4
28+
with:
29+
persist-credentials: false
30+
31+
- uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # [email protected]
32+
with:
33+
bundler-cache: false
34+
35+
- name: bootstrap
36+
run: script/bootstrap
37+
38+
# IMPORTANT: this step MUST export for the following outputs:
39+
# gem_name: the name of the gem - ex: "my-cool-gem"
40+
# gem_version: the version of the gem - ex: "1.0.0"
41+
# gem_path: the path/filename of the gem - ex: "my-cool-gem-1.0.0.gem"
42+
- name: build
43+
id: build
44+
run: script/build
45+
46+
- name: upload artifact
47+
uses: actions/[email protected]
48+
id: upload-artifact
49+
with:
50+
path: "${{ steps.build.outputs.gem_path }}"
51+
52+
release:
53+
needs: build
54+
environment: release
55+
runs-on: ubuntu-latest
56+
permissions:
57+
contents: write
58+
packages: write
59+
id-token: write
60+
steps:
61+
- uses: actions/checkout@v4
62+
with:
63+
persist-credentials: false
64+
65+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
66+
with:
67+
artifact-ids: ${{ needs.build.outputs.artifact-id }}
68+
69+
- name: Publish to GitHub Packages
70+
env:
71+
OWNER: ${{ github.repository_owner }}
72+
GEM_NAME: ${{ needs.build.outputs.gem_name }}
73+
GEM_VERSION: ${{ needs.build.outputs.gem_version }}
74+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
75+
ARTIFACT_PATH: "artifact"
76+
run: |
77+
GEM_HOST_API_KEY=${GITHUB_TOKEN} gem push --key github --host https://rubygems.pkg.github.com/${OWNER} $ARTIFACT_PATH/${GEM_NAME}-${GEM_VERSION}.gem
78+
79+
- uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # [email protected]
80+
with:
81+
bundler-cache: false
82+
83+
- name: bootstrap
84+
run: script/bootstrap
85+
86+
- name: Configure RubyGems Credentials
87+
uses: rubygems/configure-rubygems-credentials@e3f5097339179e0d4c7321ab44209e7e02446746 # pin@main
88+
89+
- name: sign ruby gem
90+
env:
91+
GEM_NAME: ${{ needs.build.outputs.gem_name }}
92+
GEM_VERSION: ${{ needs.build.outputs.gem_version }}
93+
ARTIFACT_PATH: "artifact"
94+
run: bundle exec sigstore-cli sign ${ARTIFACT_PATH}/${GEM_NAME}-${GEM_VERSION}.gem --bundle ${GEM_NAME}-${GEM_VERSION}.sigstore.json
95+
96+
- name: Publish to RubyGems
97+
env:
98+
GEM_NAME: ${{ needs.build.outputs.gem_name }}
99+
GEM_VERSION: ${{ needs.build.outputs.gem_version }}
100+
ARTIFACT_PATH: "artifact"
101+
run: gem push ${ARTIFACT_PATH}/${GEM_NAME}-${GEM_VERSION}.gem --attestation ${GEM_NAME}-${GEM_VERSION}.sigstore.json
102+
103+
- name: await gem
104+
env:
105+
GEM_NAME: ${{ needs.build.outputs.gem_name }}
106+
GEM_VERSION: ${{ needs.build.outputs.gem_version }}
107+
run: bundle exec rubygems-await "${GEM_NAME}:${GEM_VERSION}" --timeout 120
108+
109+
- name: GitHub Release
110+
env:
111+
GEM_NAME: ${{ needs.build.outputs.gem_name }}
112+
GEM_VERSION: ${{ needs.build.outputs.gem_version }}
113+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
114+
ARTIFACT_PATH: "artifact"
115+
run: |
116+
gh release create "v${GEM_VERSION}" \
117+
"${ARTIFACT_PATH}/${GEM_NAME}-${GEM_VERSION}.gem" \
118+
"${GEM_NAME}-${GEM_VERSION}.sigstore.json" \
119+
--title "v${GEM_VERSION}" \
120+
--generate-notes
121+
122+
sign:
123+
needs: [build, release]
124+
runs-on: ubuntu-latest
125+
permissions:
126+
id-token: write
127+
attestations: write
128+
contents: read
129+
130+
steps:
131+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
132+
with:
133+
artifact-ids: ${{ needs.build.outputs.artifact-id }}
134+
135+
- name: attest build provenance
136+
uses: actions/[email protected]
137+
with:
138+
subject-path: "artifact/${{ needs.build.outputs.gem_path }}"
139+
140+
verify:
141+
permissions: {}
142+
needs: [build, release, sign]
143+
runs-on: ubuntu-latest
144+
145+
steps:
146+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
147+
with:
148+
artifact-ids: ${{ needs.build.outputs.artifact-id }}
149+
150+
- name: verify
151+
env:
152+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
153+
OWNER: ${{ github.repository_owner }}
154+
REPO: ${{ github.event.repository.name }}
155+
ARTIFACT_PATH: "artifact/${{ needs.build.outputs.gem_path }}"
156+
run: gh attestation verify "$ARTIFACT_PATH" --repo ${OWNER}/${REPO} --signer-workflow ${OWNER}/${REPO}/.github/workflows/release.yml

0 commit comments

Comments
 (0)