Skip to content

nonspec: tooling for migration to a late-branching strategy, standardized devcontainers #1328

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
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
32 changes: 32 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "Jekyll and Netlify",
"image": "mcr.microsoft.com/devcontainers/universal:2",
"features": {
"ghcr.io/devcontainers/features/ruby:1": {
"version": "3.2"
}
},
"postCreateCommand": "./.devcontainer/post-create.sh",
"forwardPorts": [4000],
"portsAttributes": {
"4000": {
"label": "Jekyll Server"
}
},
"customizations": {
"vscode": {
"settings": {
"terminal.integrated.defaultProfile.linux": "bash"
},
"extensions": [
"eamodio.gitlens", // GitLens extension for Git superpowers
"github.codespaces", // Codespaces support
"github.copilot", // GitHub Copilot for AI-powered code suggestions
"github.copilot-chat", // Chat interface for GitHub Copilot
"github.github-vscode-theme", // GitHub's official VS Code theme
"github.vscode-github-actions", // GitHub Actions support
"github.vscode-pull-request-github" // GitHub Pull Requests and Issues
Copy link
Contributor Author

Choose a reason for hiding this comment

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

these are technically optional. I have no strong preference.

]
}
}
}
18 changes: 18 additions & 0 deletions .devcontainer/post-create.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
# Exit immediately if a command exits with a non-zero status
set -e

# Change to the 'docs' directory
cd docs

# Configure Bundler to install gems locally in the 'vendor/bundle' directory
bundle config set --local path 'vendor/bundle'

# Install Ruby gems specified in the Gemfile
bundle install

# Install the Netlify CLI globally using npm
npm install -g netlify-cli

# Return to the previous directory
cd ..
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ jobs:
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
- run: npm ci --ignore-scripts
- run: npm run lint --silent
- run: ./lint.sh
- run: ./tools/lint.sh
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this just adapts to the relocated script.

24 changes: 24 additions & 0 deletions .github/workflows/migrate-to-late-branch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Migrate to Late Branching Strategy

on:
workflow_dispatch: # Allows only manual triggering of the workflow

permissions:
contents: read # Minimum permission required to read the repository
pull-requests: write # Required to create branches and push changes

jobs:
migrate:
runs-on: ubuntu-latest

steps:
- name: Checkout main (no mater what else is requested)
uses: actions/checkout@v3
with:
ref: main # Checkout the main branch
fetch-depth: 1 # We don't need the full history for this operation

- name: Run migration script
run: |
chmod +x tools/migrate-to-late-branch.sh
./tools/migrate-to-late-branch.sh
68 changes: 68 additions & 0 deletions .github/workflows/netlify-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Deploy Preview to Netlify

on:
pull_request:
types: [opened, synchronize, reopened]

jobs:
if: false # This disables the entire workflow
Copy link
Contributor Author

Choose a reason for hiding this comment

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

As discussed in the meeting today, it might make more sense for this to just happen on a daily schedule, only from the main branch, and only if there are published changes to releases (or the draft spec).

this workflow tries to do the right then whenever any PR is opened to any branch? complicated.
but it would be nice to keep the preview site feature if we can prevent it from being super difficult to maintain.

deploy-preview:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install Netlify CLI
run: npm install -g netlify-cli

- name: Install dependencies
run: |
cd docs
bundle install --path vendor/bundle

- name: Build site # always use the main branch
run: |
git fetch origin main:main
git checkout main
cd docs
bundle exec jekyll build -d _site

- name: Deploy to Netlify # use the --prod flag if this is the main branch
id: netlify_deploy
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think we looked it up and we don't actually have these. Netlify is configured to pull automatically from the main branch via webhook. cc: @mlieberman85

run: |
prod_flag=""
if [ "${{ github.ref_name }}" = "main" ]; then prod_flag="--prod"; fi
cd docs
DEPLOY_URL=$(netlify deploy --dir=_site --site=$NETLIFY_SITE_ID --auth=$NETLIFY_AUTH_TOKEN $prod_flag --json | jq -r '.deploy_url')
echo "deploy_url=$DEPLOY_URL" >> $GITHUB_OUTPUT

- name: Add comment with deploy preview link
uses: actions/github-script@v7
if: ${{ github.ref_name != 'main' }} # skip if this is main branch
env:
DEPLOY_URL: ${{ steps.netlify_deploy.outputs.deploy_url }}
with:
script: |
const prNumber = context.payload.pull_request.number;
const deployUrl = process.env.DEPLOY_URL || core.getInput('deploy_url') || '${{ steps.netlify_deploy.outputs.deploy_url }}';
github.rest.issues.createComment({
issue_number: prNumber,
owner: context.repo.owner,
repo: context.repo.repo,
body: `🚀 Netlify Preview: [View Site](${deployUrl})`
});
31 changes: 31 additions & 0 deletions .github/workflows/update-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Create Release on Release Branch Update

on:
push:
branches:
- 'releases/*'

jobs:
if: false # This disables the entire workflow
create-release:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Get version from branch name
id: get_version
run: |
BRANCH_NAME="${GITHUB_REF#refs/heads/releases/}"
echo "version=$BRANCH_NAME" >> $GITHUB_OUTPUT

- name: Create GitHub Release with CLI
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${GITHUB_REF#refs/heads/releases/}"
gh release create "$VERSION" \
--title "Release $VERSION" \
--notes "Automated release from branch $GITHUB_REF" \
--repo "$GITHUB_REPOSITORY" \
--generate-notes || echo "Release already exists, skipping."
Copy link
Contributor Author

Choose a reason for hiding this comment

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

probably we'd want to delete and replace any existing releases when this happens?

54 changes: 54 additions & 0 deletions tools/create-spec-release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/bin/bash

# --- Ensure script is run from the repo root ---
REPO_ROOT="$(git rev-parse --show-toplevel)"
if [[ "$PWD" != "$REPO_ROOT" ]]; then
echo "Error: Please run this script from the repository root: $REPO_ROOT"
exit 1
fi
Comment on lines +5 to +8
Copy link
Member

Choose a reason for hiding this comment

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

Can't you just start with cd "$REPO_ROOT" and be done?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that would probably work -- unclear if errors or fixes are better?

Copy link
Member

Choose a reason for hiding this comment

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

I generally find it annoying when a program tells me I should do something else rather than just doing it. I always think: "what don't you just do it if you know what needs to be done??"
You could print out a message explaining the change of current directory before doing it so that if anything goes wrong the user isn't left disoriented but that's all that's needed in my opinion.


# --- Check for uncommitted changes ---
if [[ -n $(git status --porcelain) ]]; then
echo "Error: You have uncommitted changes. Please commit or stash them first."
exit 1
fi

# --- Look up current ref and extract the version from it ---
# If on a release branch, use the version from the branch name.
# If on main, use "draft" as the version.
# Otherwise, exit with an error.
BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD)
if [[ "$BRANCH_NAME" =~ ^releases/([^/]+)$ ]]; then
VERSION="${BASH_REMATCH[1]}"
elif [[ "$BRANCH_NAME" == "main" ]]; then
VERSION="draft"
else
echo "Error: This script must be run from a 'releases/*' or 'main' branch. Current branch: $BRANCH_NAME"
exit 1
fi

# --- Create a zip file of the spec directory ---
zip -r spec.zip spec
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this script won't work unless we've already migrated the repo. I can remove it from this PR if it's confusing.

if [[ $? -ne 0 ]]; then
echo "Error: Failed to create spec.zip."
exit 1
fi
echo "Created spec.zip successfully."

# --- Delete existing release with this version, if it exists ---
if gh release view "$VERSION" > /dev/null 2>&1; then
gh release delete "$VERSION" --yes
fi

# --- Optionally generate an attestation if running in GitHub Actions ---
if [[ -n "$GITHUB_ACTIONS" ]]; then
gh attestation generate build-provenance \
--repo "$GITHUB_REPOSITORY" \
--subject-path spec.zip \
--output spec.attestation.json
fi

# --- Create a new release and upload the spec artifact and attestation ---
gh release create "$VERSION" spec.zip \
--title "Release $VERSION" \
--notes "This is the release of the spec. The source artifact and attestation are attached."
File renamed without changes.
67 changes: 67 additions & 0 deletions tools/migrate-to-late-branch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/bin/bash

# This is a one-time script to migrate the slsa repo to a late-branch model.
# Currently, all versions are in subfolders in docs/spec/<version>
#
# For each subfolder of docs/spec on the main branch:
# 1. Checkout the main branch. Create a branch with the subfolder name and check it out.
# 2. On this branch, remove all other spec versions, the content for this release should exist directly under /spec/
# 3. Commit the result and publish the branch to the remote.

set -euo pipefail

# --- Ensure script is run from the repo root ---
REPO_ROOT="$(git rev-parse --show-toplevel)"
if [[ "$PWD" != "$REPO_ROOT" ]]; then
echo "Error: Please run this script from the repository root: $REPO_ROOT"
exit 1
fi

# --- Check for uncommitted changes ---
if [[ -n $(git status --porcelain) ]]; then
echo "Error: You have uncommitted changes. Please commit or stash them first."
exit 1
fi

# --- Save the current branch to return to later ---
ORIG_BRANCH=$(git rev-parse --abbrev-ref HEAD)

# --- Find all subfolders in docs/spec ---
SPECDIR="docs/spec"
if [[ ! -d "$SPECDIR" ]]; then
echo "Error: $SPECDIR does not exist."
exit 1
fi

# --- Start from the root of the repo ---
cd "$(git rev-parse --show-toplevel)"

# --- Collect all released version subfolders before starting the loop ---
VERSIONS=($(ls -1 "$SPECDIR" | grep -vE '^\.|^README|^draft$'))
REF_SPEC="releases"

for version in "${VERSIONS[@]}"; do
# --- Create a new branch for this version ---
BRANCH="$REF_SPEC/$version"
git checkout -b "$BRANCH"

# --- move the version folder to the root of the spec directory ---
mv "$SPECDIR/$version" "spec"

# --- remove docs folder ---
rm -rf docs

# --- Commit the changes ---
git add --all
git commit -m "Migrate $version to its own branch ($BRANCH)."
git push -u origin "$BRANCH"

# --- Return to the original branch ---
git checkout "$ORIG_BRANCH"
done

# Summary of updated branches
echo "Done. All branches created:"
for v in "${VERSIONS[@]}"; do
echo " - $REF_SPEC/$v"
done