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
12 changes: 12 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ jobs:
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v4
with:
# Full history: bin/generate_last_modified.rb derives per-file dates
# via `git log -1 --format=%cI`. A shallow (depth-1) checkout collapses
# every file to the tip commit's date, so last_modified.yml regenerates
# differently than committed and fails validate:generated_freshness.
fetch-depth: 0
- name: Set up Node
uses: actions/setup-node@v4
with:
Expand All @@ -36,6 +42,12 @@ jobs:
run: ./bin/pipeline ci
- name: Playwright smoke check
timeout-minutes: 12
env:
# The first pwcli command cold-fetches @playwright/cli and its browser;
# on a fresh runner that exceeds the harness's 20s per-command timeout
# and aborts smoke at status 124 before any assertion runs. Loosen the
# cap for CI only — local runs keep the fast 20s default.
PWCLI_CMD_TIMEOUT: 180s
run: |
set -o pipefail
./bin/pipeline smoke 2>&1 | tee tmp/playwright-smoke.log
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# Full history: bin/generate_last_modified.rb derives per-file dates
# via `git log -1 --format=%cI`. A shallow (depth-1) checkout collapses
# every file to the tip commit's date, so last_modified.yml regenerates
# differently than committed and fails validate:generated_freshness.
fetch-depth: 0
- name: Set up Node
uses: actions/setup-node@v4
with:
Expand All @@ -26,6 +32,12 @@ jobs:
run: ./bin/pipeline validate
- name: Playwright smoke check
timeout-minutes: 12
env:
# The first pwcli command cold-fetches @playwright/cli and its browser;
# on a fresh runner that exceeds the harness's 20s per-command timeout
# and aborts smoke at status 124 before any assertion runs. Loosen the
# cap for CI only — local runs keep the fast 20s default.
PWCLI_CMD_TIMEOUT: 180s
run: |
set -o pipefail
./bin/pipeline smoke 2>&1 | tee tmp/playwright-smoke.log
Expand Down
26 changes: 13 additions & 13 deletions _data/community_stories.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
generated_at: '2026-06-29T01:31:09Z'
generated_at: '2026-07-08T12:57:57Z'
tracks:
- id: craftsmanship-lineage
title: Craftsmanship Lineage
Expand All @@ -10,15 +10,15 @@ tracks:
as it moved from hallway conversations into durable community practice.
interview_ids:
- sergio-pereira-chicago-alt-net-software-craftsmanship-north-america-2011
- ray-hightower-chicagoruby-software-craftsmanship-north-america-2011
- michael-norton-cleveland-pittsburgh-community-software-craftsmanship-north-america-2011
- london-software-craftsmanship-software-craftsmanship-north-america-2011
- max-lancaster-dc-alt-net-software-craftsmanship-north-america-2011
- zach-shaw-boston-sc-software-craftsmanship-north-america-2011
- bobby-johnson-south-sound-net-software-craftsmanship-north-america-2011
- charler-baker-denver-community-software-craftsmanship-north-america-2011
- drew-shefman-houston-adobe-user-group-software-craftsmanship-north-america-2011
- dustin-updyke-pittsburgh-sc-software-craftsmanship-north-america-2011
- london-software-craftsmanship-software-craftsmanship-north-america-2011
- max-lancaster-dc-alt-net-software-craftsmanship-north-america-2011
- michael-norton-cleveland-pittsburgh-community-software-craftsmanship-north-america-2011
- ray-hightower-chicagoruby-software-craftsmanship-north-america-2011
- ross-south-bend-software-craftsmanship-software-craftsmanship-north-america-2011
- bobby-johnson-south-sound-net-software-craftsmanship-north-america-2011
- id: user-groups-as-learning-systems
title: User Groups as Learning Systems
summary: Conversations rooted in user-group ecosystems where engineers shared methods,
Expand All @@ -41,11 +41,11 @@ tracks:
interview_ids:
- justin-love-windycityrails-2012
- milan-dobrota-jen-lindner-windycityrails-2012
- stephen-anderson-windycityrails-2012
- ryan-singer-windycityrails-2012
- kevin-zolkiewiecz-windycityrails-2012
- ginny-hendry-windycityrails-2012
- eric-macadie-windycityrails-2012
- adam-grandy-windycityrails-2012
- benjamin-oakes-windycityrails-2012
- brian-liles-windycityrails-2012
- eric-macadie-windycityrails-2012
- ginny-hendry-windycityrails-2012
- jim-remsik-windycityrails-2012
- kevin-zolkiewiecz-windycityrails-2012
- movie-on-9-6-12-at-1-05-pm-windycityrails-2012
- adam-grandy-windycityrails-2012
20 changes: 10 additions & 10 deletions _data/interview_topics.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
generated_at: '2026-06-29T01:31:09Z'
generated_at: '2026-07-08T12:57:57Z'
summary:
total_topics: 72
total_interviews_with_topics: 183
Expand All @@ -10,13 +10,13 @@ items:
count: 29
transcript_count: 29
sample_interview_ids:
- chad-fowler-goto-conference-2015
- anita-sengupta-goto-conference-2015
- corey-haines-goto-conference-2015
- trisha-gee-goto-conference-2015
- rebecca-parsons-goto-conference-2015
- max-de-marzi-goto-conference-2015
- dean-wampler-goto-conference-2015
- corey-haines-goto-conference-2015
- chad-fowler-goto-conference-2015
- anita-sengupta-goto-conference-2015
- alexandra-masterson-goto-conference-2015
- slug: developer-community-and-conference-conversations
topic: developer community and conference conversations
Expand All @@ -26,11 +26,11 @@ items:
- interview-with-eric-kingery-general
- interview-with-stephen-anderson-general
- interview-with-carina-c-zona-general
- interview-with-katrina-owen-general
- interview-with-zachary-shaw-general
- interview-with-katrina-owen-general
- interview-with-michael-ficarra-general
- interview-with-rob-reynolds-general
- interview-with-randy-ellis-general
- interview-with-sandro-mancuso-and-tom-brand-general
- interview-with-ryan-slobojan-general
- slug: community-building-and-user-group-organizing
topic: community building and user-group organizing
count: 21
Expand All @@ -39,8 +39,8 @@ items:
- ryan-gerry-goto-conference-2014
- max-de-marzi-goto-conference-2014
- fred-guime-goto-conference-2014
- micah-martin-software-craftsmanship-north-america-2013
- sandro-mancuso-software-craftsmanship-north-america-2013
- micah-martin-software-craftsmanship-north-america-2013
- adewale-oshineye-software-craftsmanship-north-america-2013
- stephen-anderson-software-craftsmanship-north-america-2013
- mike-stringer-general
Expand All @@ -50,8 +50,8 @@ items:
transcript_count: 18
sample_interview_ids:
- russ-olsen-goto-conference-2014
- interview-with-giles-bowkett-author-rails-general
- interview-with-matt-ruby-creator-of-vooza-general
- interview-with-giles-bowkett-author-rails-general
- ashe-dryden-general
- james-edward-grey-iii-general
- charles-oliver-nutter-general
Expand All @@ -74,8 +74,8 @@ items:
count: 7
transcript_count: 7
sample_interview_ids:
- bill-scott-general
- kumar-mcmillan-general
- bill-scott-general
- daniel-x-o-neil-general
- arthur-kay-general
- carl-erickson-software-craftsmanship-north-america-2012
Expand Down
4 changes: 3 additions & 1 deletion bin/generate_community_stories_page.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
OUT_PAGE_PATH = File.join(ROOT, "interviews", "stories", "index.html")

interviews = Generators::Core::YamlIo.load(INTERVIEWS_PATH, key: "items")
sorted = interviews.sort_by { |item| item["recorded_date"].to_s }
# Tiebreaker on id: recorded_date has ties and sort_by is not stable, so the
# first(10) track selections below must not depend on sort-impl tie order.
sorted = interviews.sort_by { |item| [item["recorded_date"].to_s, item["id"].to_s] }

craftsmanship = sorted.select do |item|
item["conference"].to_s.downcase.include?("software craftsmanship")
Expand Down
5 changes: 4 additions & 1 deletion bin/generate_interview_topics_page.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ def slugify(value)
end

topic_items = topics.map do |topic, rows|
sorted_rows = rows.sort_by { |row| row["recorded_date"].to_s }.reverse
# Tiebreaker on id: recorded_date has ties (e.g. 7 interviews on one date), and
# sort_by is not stable, so first(N) sampling below would depend on sort-impl
# tie order. Committed output must be a pure function of data — id makes it total.
sorted_rows = rows.sort_by { |row| [row["recorded_date"].to_s, row["id"].to_s] }.reverse
transcript_count = sorted_rows.count do |row|
asset = assets_by_id[row["video_asset_id"]]
asset && !asset["transcript_id"].to_s.strip.empty?
Expand Down
6 changes: 6 additions & 0 deletions bin/validate_generated_freshness.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,10 @@ def git_diff_names(paths)
warn 'Generated artifact freshness validation failed:'
warn ' Run `bundle exec rake build` and commit regenerated tracked artifacts.'
changed.each { |path| warn " - #{path}" }

# Print the actual drift, not just filenames. Without this the gate is a black
# box — you see WHICH files differ but not HOW, which turns a CI-only reproduction
# into guesswork. --no-color keeps the log diff-clean.
diff, = Open3.capture2('git', '--no-pager', 'diff', '--no-color', '--', *changed, chdir: ROOT)
warn "\n--- drift diff ---\n#{diff}"
exit 1
Loading