Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
48aa82e
Fix code-comment contrast to meet WCAG AA (#937)
vortsghost2025 Oct 17, 2026
ea82d68
docs: fix KTO data-shape row to use completion column (#938)
vortsghost2025 Oct 17, 2026
9e6a8b2
chore: add community-health files for contributor intake (#964)
cemililik Oct 17, 2026
0766e94
docs(usermanuals): name the real KTO columns on the alignment overvie…
Venius24 Oct 17, 2026
6c55900
docs: send newcomers to a Front door view and state that closing is n…
cemililik Oct 17, 2026
56b4f0d
feat(ci): let a contributor claim a good first issue with /assign (#978)
cemililik Oct 18, 2026
675c3e3
chore: housekeeping — stale requirements files, roadmap corrections, …
cemililik Oct 18, 2026
48c7582
feat(export): write the SHA-256 sidecar verify-gguf relies on, and do…
cemililik Oct 18, 2026
ef41461
fix: rope_scaling on transformers 5, hub telemetry, reserved retentio…
cemililik Oct 18, 2026
700b6d6
docs: webhooks, DeepSpeed presets, first-run output tree and --offlin…
cemililik Oct 18, 2026
cb5db50
fix(ci): make dependabot.yml parse by dropping versioning-strategy wi…
cemililik Oct 18, 2026
86eb1f7
docs: compliance and privacy wording, SBOM and Article 12/14, and the…
cemililik Oct 18, 2026
10fc5a5
chore(deps): admit pypdf 6, xxhash 4, datasketch 2 and pytest-randoml…
cemililik Oct 18, 2026
b8d2643
chore(ci): bump checkout 7, setup-python 7, download-artifact 8, depl…
cemililik Oct 18, 2026
306c976
chore(deps): update huggingface-hub requirement from <2.0.0,>=1.5.0 t…
dependabot[bot] Oct 18, 2026
e5c0eb1
fix(cli): preserve root flags before subcommands (#1012)
hiyouwhatsapp Oct 18, 2026
cfba929
test(quickstart): cover non-CUDA VRAM fallback (#1013)
hiyouwhatsapp Oct 18, 2026
80ac549
fix: torch floor 2.7.0, Gemma 3 RoPE and text-config sliding window, …
cemililik Oct 19, 2026
0620ca0
Merge branch 'main' into development
cemililik Oct 19, 2026
a761724
Merge branch 'main' into development (#1020)
cemililik Oct 19, 2026
c61d573
chore(ci): bump actions/upload-artifact from 5 to 7 (#1022)
dependabot[bot] Oct 19, 2026
bd7a7c3
chore(ci): bump actions/github-script from 8 to 9 (#1023)
dependabot[bot] Oct 19, 2026
7d7fc4b
chore(ci): bump actions/upload-pages-artifact from 3 to 5 (#1021)
dependabot[bot] Oct 19, 2026
f180dca
chore(ci): bump actions/configure-pages from 5 to 6 (#1024)
dependabot[bot] Oct 19, 2026
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
1 change: 0 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,4 @@ CODE_OF_CONDUCT.md
# Build tooling not needed by the installed package
tools/
MANIFEST.in
requirements*.txt
docker-compose.yaml
25 changes: 25 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Code owners for ForgeLM.
#
# When a pull request is opened, GitHub requests a review from the owner of each
# path it changes. This file only routes those review requests: whether a review
# is *required* before merging is a branch-protection setting, not anything an
# entry here can turn on. See docs/standards/code-review.md for the review
# standard and GOVERNANCE.md for how ownership is granted.
#
# These rules are evaluated last-match-wins, so a more specific pattern placed
# below `*` overrides it. When an area gets its own owner, add their line below
# the default rather than replacing it, so the default owner stays on every path
# an area owner does not name. GitHub does not request a review for a draft or a
# draft pull request.

* @cemililik

# Repository scaffolding and policy files stay with the default owner even after
# an area owner is added, because these paths define the rules the area owners
# work under.
/.github/ @cemililik
/CONTRIBUTING.md @cemililik
/GOVERNANCE.md @cemililik
/MAINTAINERS.md @cemililik
/SECURITY.md @cemililik
/pyproject.toml @cemililik
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ contact_links:
- name: Report a security vulnerability
url: https://github.com/HodeTech/ForgeLM/security/advisories/new
about: Report vulnerabilities privately, never in a public issue (see SECURITY.md)
- name: Documentation
- name: Browse the documentation
url: https://github.com/HodeTech/ForgeLM/tree/main/docs
about: Check the docs and guides before opening an issue
about: Read the docs and guides before opening a documentation issue
- name: Discussions (Q&A)
url: https://github.com/HodeTech/ForgeLM/discussions
about: Ask questions and get help from the community
52 changes: 52 additions & 0 deletions .github/ISSUE_TEMPLATE/documentation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Documentation
description: Report a documentation error, or propose an improvement to a guide or its Turkish mirror
labels: ["documentation", "needs-triage"]
body:
- type: markdown
attributes:
value: |
Thanks for improving the docs! One correction per issue is easiest to review.

User-facing documentation is kept as an English page **and** a Turkish
mirror, and the two are updated together — see
[CONTRIBUTING.md](https://github.com/HodeTech/ForgeLM/blob/development/CONTRIBUTING.md).
You do not need to write the Turkish yourself: open the pull request with
the English change and say so, and a maintainer will complete the mirror.
Tell us below which copy you were reading. Documentation pull requests are
welcome directly.

- type: input
id: page
attributes:
label: Page or file
description: The repository path or the documentation-site page you were reading.
placeholder: docs/guides/quickstart.md — or the Quick start page on the docs site
validations:
required: true

- type: textarea
id: problem
attributes:
label: What is wrong or missing?
description: What does the page say, and what does the reader need instead?
validations:
required: true

- type: textarea
id: suggestion
attributes:
label: Suggested wording (optional)
description: If you already know the fix, propose the text. We will tidy the language if needed.

- type: dropdown
id: language
attributes:
label: Which copy is affected?
description: User-facing docs are maintained as an English page and a Turkish mirror. An issue that needs mirror work is labelled `i18n` when it is triaged.
options:
- English
- Turkish
- Both
- Not sure
validations:
required: true
64 changes: 64 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Dependabot configuration for ForgeLM.
#
# Dependabot opens a pull request when a dependency's declared range no longer
# covers the newest release. It is the upstream half of the supply-chain story:
# `tools/check_pip_audit.py` and the nightly CVE job catch known advisories, and
# these pull requests make a fix reachable.
#
# No `versioning-strategy` is set for `pip`. The `pip` ecosystem accepts only `auto`,
# `increase`, `increase-if-necessary` and `lockfile-only`; a previous `widen` is not
# among them, GitHub rejected the whole file ("did not match one of the following
# values"), and while it did not parse Dependabot opened nothing. ForgeLM declares
# bounded ranges (`>=floor,<next-major`) with no lockfile, so the default (`auto`) may
# raise a floor the ceiling already covers instead of admitting a new major; look at the
# first pull requests and tighten this then.
#
# `ruff`, `mypy` and `bandit` are ignored on purpose. They are blocking CI gates
# and `tests/test_packaging.py` requires their `[dev]` range to equal the one
# `ci.yml`'s lint job installs. Dependabot edits only `pyproject.toml`, so a bump
# would fail that test the moment it arrived. Those three are raised deliberately,
# in one commit, with the CI pin moved in step.

version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 5
labels:
- "dependencies"
- "area: packaging-ci"
commit-message:
prefix: "chore(deps)"
ignore:
- dependency-name: "ruff"
- dependency-name: "mypy"
- dependency-name: "bandit"
groups:
python-minor-and-patch:
patterns:
- "*"
update-types:
- "minor"
- "patch"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 5
labels:
- "dependencies"
- "area: packaging-ci"
commit-message:
prefix: "chore(ci)"
groups:
actions-minor-and-patch:
patterns:
- "*"
update-types:
- "minor"
- "patch"
47 changes: 47 additions & 0 deletions .github/workflows/assign-on-comment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Assign on comment

# A contributor claims an issue by commenting `/assign` and gives it back with `/unassign`.
# The rules live in tools/assign_on_comment.py (documented in CONTRIBUTING.md, "Working on an issue").
#
# This is the one workflow that runs on text written by anyone, with permission to write to issues.
# Keep it that way on purpose; tests/test_assign_on_comment.py pins each of these properties:
# - the trigger is `issue_comment` / `created` only (an edited comment cannot start a run);
# - the job `if:` reads event data only, never a shell: no `${{ }}` appears in a `run:` line,
# and the script reads the event file itself;
# - the token holds `contents: read` and `issues: write` and nothing else;
# - the checkout takes the default branch (what `issue_comment` runs on), one file, no stored credentials,
# and is pinned to a full commit SHA;
# - there is no `concurrency:` group: GitHub cancels a *pending* run when a newer one joins the group, which
# would drop a claim without a word. Instead the script decides again on a fresh read right before it
# writes, and after writing steps back only itself if a simultaneous claim collided (a maintainer wins;
# between two contributors the earlier login stays; a claim that would exceed the limit is released).
#
# Maintainers: to switch the feature off at once, open Actions > "Assign on comment" > the "..." menu >
# "Disable workflow". Assignments already made stay as they are. Changing who an issue is assigned to is a
# maintainer's decision, made in the issue's sidebar; nothing here ever overrides it.

on:
issue_comment:
types: [created]

permissions: {}

jobs:
assign:
# Event data only. Skips pull-request comments and bots, and runs only for a comment that starts with a command.
if: ${{ !github.event.issue.pull_request && github.event.comment.user.type != 'Bot' && (startsWith(github.event.comment.body, '/assign') || startsWith(github.event.comment.body, '/unassign')) }}
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: read # the checkout reads one script from the default branch
issues: write # add or remove the assignee, and post the reply
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
sparse-checkout: tools/assign_on_comment.py
sparse-checkout-cone-mode: false
- name: Assign or release the issue
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: python3 tools/assign_on_comment.py
20 changes: 13 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v7
with:
persist-credentials: false

- uses: actions/setup-python@v6
- uses: actions/setup-python@v7
with:
python-version: "3.11"

Expand Down Expand Up @@ -118,9 +120,11 @@ jobs:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v7
with:
persist-credentials: false

- uses: actions/setup-python@v6
- uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}
cache: pip
Expand Down Expand Up @@ -148,7 +152,7 @@ jobs:
- name: Upload coverage (3.11 only)
# Upload coverage from one combo only — avoids 4× artifact duplication; 3.11 is canonical (matches publish.yml build job).
if: matrix.python-version == '3.11' && always()
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v7
with:
name: coverage-report
path: coverage.xml
Expand All @@ -159,14 +163,16 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v7
with:
persist-credentials: false

- uses: actions/setup-node@v7
with:
node-version: "24"
package-manager-cache: false

- uses: actions/setup-python@v6
- uses: actions/setup-python@v7
with:
python-version: "3.11"
cache: pip
Expand Down
49 changes: 31 additions & 18 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ jobs:
matrix:
python-version: ["3.11", "3.12"]
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v7
with:
persist-credentials: false

- uses: actions/setup-python@v6
- uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}

Expand Down Expand Up @@ -149,9 +151,11 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v7
with:
persist-credentials: false

- uses: actions/setup-python@v6
- uses: actions/setup-python@v7
with:
python-version: "3.11"

Expand Down Expand Up @@ -218,9 +222,11 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v7
with:
persist-credentials: false

- uses: actions/setup-python@v6
- uses: actions/setup-python@v7
with:
python-version: "3.10"

Expand All @@ -237,14 +243,19 @@ jobs:
# EXPLICITLY so this job tests the true documented minimum — trl puts
# no upper bound on transformers, so an unpinned resolve would silently
# pull the newest 5.x and stop exercising the floor. transformers
# 5.3.0 is the CVE-2026-4372 fix floor and requires torch>=2.4 /
# huggingface_hub>=1.3 / tokenizers>=0.22; trl 1.0.0 pulls the
# accelerate>=1.4 and datasets>=4.7 floor. Keep 1:1 with the pyproject
# [project].dependencies minimums.
# 5.10.1 is the first installable release past CVE-2026-4372,
# CVE-2026-5241 and CVE-2026-9856 (5.10.0, which carries the last of
# them, was yanked); it requires huggingface_hub>=1.5 /
# tokenizers>=0.22 and imports torch.float8_e8m0fnu, which first
# exists in torch 2.7.0 (this job failed on torch 2.4.0 with
# AttributeError at `import transformers`); trl 1.0.0
# pulls the accelerate>=1.4 and datasets>=4.7 floor. Keep 1:1 with the
# pyproject [project].dependencies minimums (tests/test_packaging.py
# compares them).
pip install \
"torch==2.4.0" \
"transformers==5.3.0" \
"huggingface_hub==1.3.0" \
"torch==2.7.0" \
"transformers==5.10.1" \
"huggingface_hub==1.5.0" \
"peft==0.19.0" \
"accelerate==1.4.0" \
"datasets==4.7.0" \
Expand All @@ -270,7 +281,7 @@ jobs:
# the moment a dependency advisory drops, even before the team
# re-bumps versions:
#
# - pip-audit (transitive CVEs against the OSV / GHSA databases)
# - pip-audit (transitive CVEs against PyPI's vulnerability data, its default service)
# - bandit (static-analysis on forgelm/ production code only)
#
# Severity policy (per tools/check_pip_audit.py + tools/check_bandit.py):
Expand All @@ -284,9 +295,11 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v7
with:
persist-credentials: false

- uses: actions/setup-python@v6
- uses: actions/setup-python@v7
with:
python-version: "3.11"
cache: pip
Expand Down Expand Up @@ -335,7 +348,7 @@ jobs:

- name: Upload security scan artifacts
if: always()
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v7
with:
name: supply-chain-scans
path: |
Expand All @@ -352,7 +365,7 @@ jobs:
issues: write # required for creating failure notification issues
steps:
- name: Create issue on failure
uses: actions/github-script@v8
uses: actions/github-script@v9
with:
script: |
const title = `Nightly CI failure — ${new Date().toISOString().split('T')[0]}`;
Expand Down
Loading
Loading