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
11 changes: 7 additions & 4 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ Key directories and files:
- `Gemfile` - Ruby dependencies specification
- `_layouts/` - Jekyll layout templates (home.html, default.html, post.html, etc.)
- `_includes/` - Jekyll include templates (quantecon-menubar.html)
- `_posts/` - Blog posts and news articles (sorted chronologically)
- `_posts/` - News posts, written by people (sorted chronologically)
- `_data/activity/` - Activity feed data (library releases, lecture updates), written by the reporter bot — see "News and Activity" in README.md
- `_lectures/` - Collection of lecture series pages
- `_projects/` - Collection of project pages
- `_team-members/` - Collection of team member profiles
Expand All @@ -48,7 +49,7 @@ Key directories and files:
### Common Operations

**Adding new content:**
- Blog posts: Add markdown files to `_posts/` with format `YYYY-MM-DD-title.md`
- News posts: Add markdown files to `_posts/` with format `YYYY-MM-DD-title.md` — only for announcements (new projects, grants, people, workshops); releases and lecture updates belong in Activity (see "News and Activity" in README.md)
- Team members: Add markdown files to `_team-members/` — `role` picks the section on the team page and `tag` the badge; the Translators section instead lists anyone with a `translator` field (e.g. `translator: "Chinese Editor"`), so a member can appear there as well as in their own section
- Lectures: Add markdown files to `_lectures/`
- Workshops: Add to `pages/workshops.md` **and** update the hardcoded "Recent Workshops" list in `_layouts/home.html` (see #197 for planned automation)
Expand All @@ -69,13 +70,14 @@ Key directories and files:
4. Navigate through the main sections:
- Home page - verify layout and content load
- Lectures page - verify lecture series are listed
- News page - verify blog posts display
- News page - verify news posts display
- Activity page - verify entries from `_data/activity/` display, grouped by month
- About page - verify team information
- Navigation menu - verify all links work
5. Test responsive design by resizing browser window
6. Verify images and styling load correctly

**No formal testing infrastructure exists** - validation is done through manual browser testing.
**No formal testing infrastructure exists** - validation is done through manual browser testing. The one automated check is `ruby .github/scripts/check-activity-data.rb`, which CI runs to validate the Activity data files.

**No linting or formatting commands** - the repository has minimal tooling beyond Jekyll itself.

Expand Down Expand Up @@ -154,6 +156,7 @@ bundle exec jekyll build
├── Gemfile
├── README.md
├── _config.yml
├── _data/activity/
├── _includes/
├── _layouts/
├── _lectures/
Expand Down
82 changes: 82 additions & 0 deletions .github/scripts/check-activity-data.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Check the Activity feed data in _data/activity/*.yml against the schema in
# README.md ("News and Activity"). The reporter bot writes these files, so a bad
# file should fail its PR with a message that names the file, rather than break
# the Jekyll build or render silently.
require "date"
require "yaml"

DATA_DIR = File.expand_path("../../_data/activity", __dir__)
TYPES = %w[release lectures translation].freeze
REQUIRED = %w[date type project url].freeze
PULL_URL = %r{\Ahttps://github\.com/[^/]+/[^/]+/pull/\d+\z}

def blank?(value)
value.nil? || value.to_s.strip.empty?
end

paths = Dir.glob(File.join(DATA_DIR, "*.{yml,yaml}")).sort
if paths.empty?
puts "::error::No Activity data files found in #{DATA_DIR}"
exit 1
end

errors = []
paths.each do |full_path|
path = full_path.delete_prefix("#{File.expand_path('../..', __dir__)}/")
begin
entries = YAML.safe_load(File.read(full_path), permitted_classes: [Date])
rescue Psych::Exception => e
errors << "#{path}: invalid YAML (#{e.message})"
next
end
unless entries.is_a?(Array) && !entries.empty?
errors << "#{path}: must be a non-empty list of entries"
next
end

entries.each_with_index do |entry, i|
where = "#{path}, entry #{i + 1}"
unless entry.is_a?(Hash)
errors << "#{where}: must be a mapping"
next
end
missing = REQUIRED.select { |key| blank?(entry[key]) }
errors << "#{where}: missing #{missing.join(', ')}" unless missing.empty?
errors << "#{where}: date must be an unquoted YYYY-MM-DD date" if entry["date"] && !entry["date"].is_a?(Date)
errors << "#{where}: type must be one of #{TYPES.join(', ')}" if entry["type"] && !TYPES.include?(entry["type"])
errors << "#{where}: url must start with https://" unless blank?(entry["url"]) || entry["url"].to_s.start_with?("https://")
if entry["type"] == "translation" && !entry["project"].to_s.match?(/\A.+ \([^)]+\)\z/)
errors << "#{where}: a translation's project must be \"<series name> (<language>)\""
end
if entry["type"] == "release" && !(entry["version"].is_a?(String) && !blank?(entry["version"]))
errors << "#{where}: release entries need a version, written as a string (quote numeric-looking versions)"
end
if entry.key?("summary")
summary = entry["summary"]
if !summary.is_a?(String) || blank?(summary)
errors << "#{where}: summary must be a non-empty string (omit the key instead)"
elsif summary.count("`").odd? || summary.include?("``")
errors << "#{where}: summary has an unmatched or doubled backtick"
end
end

changes = entry["changes"] || []
unless changes.is_a?(Array)
errors << "#{where}: changes must be a list"
next
end
errors << "#{where}: changes must not be an empty list (omit the key instead)" if entry.key?("changes") && changes.empty?
changes.each_with_index do |change, j|
next if change.is_a?(Hash) && change["title"].is_a?(String) && !blank?(change["title"]) &&
change["url"].to_s.match?(PULL_URL)
errors << "#{where}, change #{j + 1}: needs a string title and a GitHub pull-request url"
end
end
end

if errors.empty?
puts "Activity data OK (#{paths.size} files)"
else
errors.each { |error| puts "::error::#{error}" }
exit 1
end
3 changes: 3 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ jobs:
ruby-version: '3.4'
bundler-cache: true

- name: Check Activity data
run: ruby .github/scripts/check-activity-data.rb

- name: Build Jekyll site
run: bundle exec jekyll build
env:
Expand Down
57 changes: 57 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,63 @@ Website for QuantEcon Organisation
bundle exec jekyll serve
```

## News and Activity

The site has two streams of updates. The rule of thumb: **people write News, the reporter bot writes Activity.** The bot never publishes to News.

| | News | Activity |
|---|---|---|
| **What goes in** | New projects (a new lecture series, book, a library's first public release, or a new language edition of a lecture series), grants and funding, people (RAs, team changes, open positions), workshops, tutorials and talks, partnerships, and changes that affect users | Every library release; changes to existing lecture series (new lectures, new sections and exercises, substantive revisions, fixes a reader would notice); updates to translated editions |
| **Written by** | A person | The reporter bot (maintained in the private `QuantEcon/reports-activity` repository) |
| **Review** | Normal PR review of the wording | None day to day: the reporter's daily PR merges itself once the data check passes (planned; until then, a light check of each PR) |

**Excluded from both:** dependency and action version bumps, CI, build, deploy and publishing-workflow changes, analytics, editor-of-record and other metadata changes, translation-sync tooling, and website changes. Releases of tooling (GitHub Actions, themes, plugins) are not library releases, and a GitHub release published later for an old version is not a new release.

**Promotion is a human decision.** When a release or a batch of lecture changes deserves wider attention, someone writes a News post that links to it.

These definitions decide which stream an item belongs to, not where it is shown. News posts are stored in `_posts/` and Activity entries in `_data/activity/` (schema below). Which pages display each stream is a design choice: today News appears on `/news/`, the home page and `feed.xml`, and Activity on `/activity/`.

### Activity data

Each reporter run adds one file per stream, `_data/activity/<run-date>-<stream>.yml`, holding a list of entries. `<stream>` is `software` for releases and `lectures` for lecture and translation updates, and a run writes no file for a stream with nothing to report. Entry dates can be earlier than the file's run date. The Activity page merges every file, orders the entries by date (newest first, and in file order within a day), and groups them by month. CI checks every file against this schema (`.github/scripts/check-activity-data.rb`).

| Field | Required | Description |
|---|---|---|
| `date` | yes | Unquoted `YYYY-MM-DD`, in UTC. For a `release`, the day it was published. For `lectures` and `translation`, the day of the first `publish-*` release that included every listed change, i.e. when it went live. |
| `type` | yes | `release`, `lectures` or `translation` |
| `project` | yes | Human-readable name, e.g. `QuantEcon.py` or `Intermediate Quantitative Economics with Python`. A translated edition is `<series name> (<language>)`, e.g. `Python Programming for Economics and Finance (French)`. |
| `url` | yes | The release notes (`release`) or the live site (`lectures`, `translation`) |
| `version` | `release` only | The released version tag, as a string, e.g. `v0.12.0` (quote numeric-looking versions such as `"1.10"`) |
| `summary` | no | One factual sentence describing what changed. Plain text, except that text in single backticks renders as inline code. |
| `changes` | no | List of `{title, url}` links to the pull requests behind the entry (GitHub pull-request URLs), merged into the default branch. Titles are plain text, lightly tidied: prefixes such as `[slug]`, `FIX:` or `chore:`, and internal notes, may be dropped. |

For example, `_data/activity/2026-09-27-lectures.yml`:

```yaml
- date: 2026-09-27
type: lectures
project: Intermediate Quantitative Economics with Python
url: https://python.quantecon.org/
summary: Added three new lectures (Linear Quadratic Mean Field Games, Investment Under Uncertainty, and Optimal Growth Under Uncertainty and Tobin's q), and added exercises to the two auction lectures.
changes:
- title: Two sequels to rational_expectations
url: https://github.com/QuantEcon/lecture-python.myst/pull/1070
- title: Add exercises and further reading
url: https://github.com/QuantEcon/lecture-python.myst/pull/1069
- title: Add VCG comparison section and exercises
url: https://github.com/QuantEcon/lecture-python.myst/pull/1068
```

and `_data/activity/2026-09-24-software.yml`:

```yaml
- date: 2026-09-24
type: release
project: QuantEcon.py
version: v0.12.0
url: https://github.com/QuantEcon/QuantEcon.py/releases/tag/v0.12.0
```

## News Post Tags

Posts in `_posts/` use a `tag` frontmatter field with coloured pill badges on the News page.
Expand Down
11 changes: 11 additions & 0 deletions _data/activity/2026-06-14-lectures.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Activity data: see "News and Activity" in README.md for the schema.
# Migrated from the reporter's post _posts/2026-06-14-lectures.md (removed); excluded items removed.

- date: 2026-06-12
type: lectures
project: Advanced Quantitative Economics with Python
url: https://python-advanced.quantecon.org/
summary: Added three lectures on contract theory under moral hazard and a lecture, Survey Data and Subjective Beliefs in Business Cycle Models.
changes:
- title: Add three lectures on contract theory and one lecture on survey data and robustness
url: https://github.com/QuantEcon/lecture-python-advanced.myst/pull/343
15 changes: 15 additions & 0 deletions _data/activity/2026-06-21-lectures.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Activity data: see "News and Activity" in README.md for the schema.
# Migrated from the reporter's post _posts/2026-06-21-lectures.md (removed); excluded items removed.

- date: 2026-06-19
type: lectures
project: Intermediate Quantitative Economics with Python
url: https://python.quantecon.org/
summary: Rewrote the Non-Conjugate Priors lecture, adding notes on NUTS and variational inference, and revised the exposition and notation of Another Look at the Kalman Filter.
changes:
- title: 'Add explanatory notes to bayes_nonconj: NUTS and variational inference'
url: https://github.com/QuantEcon/lecture-python.myst/pull/918
- title: Rewrite the Non-Conjugate Priors lecture
url: https://github.com/QuantEcon/lecture-python.myst/pull/913
- title: Update exposition of first three sections
url: https://github.com/QuantEcon/lecture-python.myst/pull/903
11 changes: 11 additions & 0 deletions _data/activity/2026-06-28-lectures.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Activity data: see "News and Activity" in README.md for the schema.
# Migrated from the reporter's post _posts/2026-06-28-lectures.md (removed); excluded items removed.

- date: 2026-06-22
type: lectures
project: Intermediate Quantitative Economics with Python
url: https://python.quantecon.org/
summary: Added three new lectures, including The Kalman Filter and Vector Autoregressions and Robust Permanent Income and Pricing.
changes:
- title: Adding Tom's new lectures on Kalman Filter and Robust Income
url: https://github.com/QuantEcon/lecture-python.myst/pull/931
13 changes: 13 additions & 0 deletions _data/activity/2026-07-05-lectures.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Activity data: see "News and Activity" in README.md for the schema.
# Migrated from the reporter's post _posts/2026-07-05-lectures.md (removed); excluded items removed.

- date: 2026-07-02
type: lectures
project: Intermediate Quantitative Economics with Python
url: https://python.quantecon.org/
summary: Replaced the LQ Consumption Smoothing lecture with a trilogy of lectures on the LQ permanent income model, and added two lectures on unemployment dynamics, A Linear Model of Unemployment and Unemployment Dynamics with Asymmetric Shocks.
changes:
- title: Add Tom's LQ permanent income trilogy of lectures
url: https://github.com/QuantEcon/lecture-python.myst/pull/943
- title: Add unemployment dynamics lectures (linear + nonlinear)
url: https://github.com/QuantEcon/lecture-python.myst/pull/928
8 changes: 8 additions & 0 deletions _data/activity/2026-07-06-software.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Activity data: see "News and Activity" in README.md for the schema.
# Migrated from the reporter's post _posts/2026-07-06-software.md (removed); excluded items removed.

- date: 2026-07-06
type: release
project: ContinuousDPs.jl
version: v0.2.0
url: https://github.com/QuantEcon/ContinuousDPs.jl/releases/tag/v0.2.0
8 changes: 8 additions & 0 deletions _data/activity/2026-07-08-software.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Activity data: see "News and Activity" in README.md for the schema.
# Migrated from the reporter's post _posts/2026-07-08-software.md (removed); excluded items removed.

- date: 2026-07-08
type: release
project: QuantEcon.py
version: v0.11.3
url: https://github.com/QuantEcon/QuantEcon.py/releases/tag/v0.11.3
19 changes: 19 additions & 0 deletions _data/activity/2026-07-12-lectures.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Activity data: see "News and Activity" in README.md for the schema.
# Migrated from the reporter's post _posts/2026-07-12-lectures.md (removed); excluded items removed.

- date: 2026-07-07
type: lectures
project: Advanced Quantitative Economics with Python
url: https://python-advanced.quantecon.org/
summary: Added a new lecture, Dynamic Supply and Demand Curves.
changes:
- title: Adding Tom's lecture on dynamic supply and demand curves
url: https://github.com/QuantEcon/lecture-python-advanced.myst/pull/352
- date: 2026-07-07
type: lectures
project: Intermediate Quantitative Economics with Python
url: https://python.quantecon.org/
summary: Added missing `pip install` cells to four lectures.
changes:
- title: Add missing pip dependencies
url: https://github.com/QuantEcon/lecture-python.myst/pull/951
8 changes: 8 additions & 0 deletions _data/activity/2026-07-13-software.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Activity data: see "News and Activity" in README.md for the schema.
# Migrated from the reporter's post _posts/2026-07-13-software.md (removed); excluded items removed.

- date: 2026-07-13
type: release
project: QuantEcon.jl
version: v0.18.0
url: https://github.com/QuantEcon/QuantEcon.jl/releases/tag/v0.18.0
28 changes: 28 additions & 0 deletions _data/activity/2026-07-15-software.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Activity data: see "News and Activity" in README.md for the schema.
# Migrated from the reporter's post _posts/2026-07-15-software.md (removed); excluded items removed.

- date: 2026-07-15
type: release
project: QuantEcon.py
version: v0.11.4
url: https://github.com/QuantEcon/QuantEcon.py/releases/tag/v0.11.4
- date: 2026-07-15
type: release
project: GameTheory.jl
version: v0.7.0
url: https://github.com/QuantEcon/GameTheory.jl/releases/tag/v0.7.0
- date: 2026-07-15
type: release
project: BasisMatrices.jl
version: v0.8.1
url: https://github.com/QuantEcon/BasisMatrices.jl/releases/tag/v0.8.1
- date: 2026-07-15
type: release
project: ContinuousDPs.jl
version: v0.2.1
url: https://github.com/QuantEcon/ContinuousDPs.jl/releases/tag/v0.2.1
- date: 2026-07-15
type: release
project: GameTracer.jl
version: v0.1.2
url: https://github.com/QuantEcon/GameTracer.jl/releases/tag/v0.1.2
8 changes: 8 additions & 0 deletions _data/activity/2026-07-20-software.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Activity data: see "News and Activity" in README.md for the schema.
# Migrated from the reporter's draft PR QuantEcon/website#241; excluded items removed.

- date: 2026-07-20
type: release
project: ContinuousDPs.jl
version: v0.3.0
url: https://github.com/QuantEcon/ContinuousDPs.jl/releases/tag/v0.3.0
13 changes: 13 additions & 0 deletions _data/activity/2026-07-26-lectures.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Activity data: see "News and Activity" in README.md for the schema.
# Migrated from the reporter's draft PR QuantEcon/website#242; excluded items removed.

- date: 2026-07-23
type: lectures
project: Intermediate Quantitative Economics with Python
url: https://python.quantecon.org/
summary: Added a new section of ten lectures on Phillips Curve Tradeoffs, and added figure captions and standardized CDF notation in the Incorrect Models lecture.
changes:
- title: Adding Tom's new section on Phillips Curve Tradeoffs
url: https://github.com/QuantEcon/lecture-python.myst/pull/992
- title: Add figure captions and use CDF
url: https://github.com/QuantEcon/lecture-python.myst/pull/982
8 changes: 8 additions & 0 deletions _data/activity/2026-07-26-software.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Activity data: see "News and Activity" in README.md for the schema.
# Migrated from the reporter's draft PR QuantEcon/website#243; excluded items removed.

- date: 2026-07-26
type: release
project: ContinuousDPs.jl
version: v0.3.1
url: https://github.com/QuantEcon/ContinuousDPs.jl/releases/tag/v0.3.1
11 changes: 11 additions & 0 deletions _data/activity/2026-08-02-lectures.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Activity data: see "News and Activity" in README.md for the schema.
# Migrated from the reporter's draft PR QuantEcon/website#246; excluded items removed.

- date: 2026-07-26
type: lectures
project: Intermediate Quantitative Economics with Python
url: https://python.quantecon.org/
summary: Added missing `quantecon` and `jax` installs to nine lectures.
changes:
- title: Add pip install cells for quantecon and jax in lectures that were missing them
url: https://github.com/QuantEcon/lecture-python.myst/pull/1006
23 changes: 23 additions & 0 deletions _data/activity/2026-08-02-software.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Activity data: see "News and Activity" in README.md for the schema.
# Migrated from the reporter's draft PR QuantEcon/website#247; excluded items removed.

- date: 2026-08-02
type: release
project: QuantEcon.jl
version: v0.19.0
url: https://github.com/QuantEcon/QuantEcon.jl/releases/tag/v0.19.0
- date: 2026-08-02
type: release
project: GameTheory.jl
version: v0.7.1
url: https://github.com/QuantEcon/GameTheory.jl/releases/tag/v0.7.1
- date: 2026-08-02
type: release
project: BasisMatrices.jl
version: v0.8.2
url: https://github.com/QuantEcon/BasisMatrices.jl/releases/tag/v0.8.2
- date: 2026-08-02
type: release
project: ContinuousDPs.jl
version: v0.3.2
url: https://github.com/QuantEcon/ContinuousDPs.jl/releases/tag/v0.3.2
Loading
Loading