Skip to content

Commit 240f04f

Browse files
committed
Add initial CHANGELOG with versioning note, plus script for automated upates
Signed-off-by: lelia <lelia@socket.dev>
1 parent 1e7e451 commit 240f04f

2 files changed

Lines changed: 387 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6+
7+
> **Versioning note:** Releases through `1.1.3` used bare semver tags (e.g. `1.1.3`).
8+
> Starting with `v2.0.0` the project follows the [GitHub Actions tag convention][gha-tags]
9+
> using a `v` prefix (e.g. `v2.0.0`) with a floating major tag (`v2`).
10+
11+
[gha-tags]: https://docs.github.com/en/actions/sharing-automations/creating-actions/releasing-and-maintaining-actions
12+
13+
---
14+
15+
## [Unreleased]
16+
17+
### Added
18+
- Multi-stage Dockerfiles for both `socket-basics` and `socket-basics-app-tests` — Trivy,
19+
TruffleHog, and Go are now pulled from their official registry images as named stages,
20+
making them Dependabot-trackable via `FROM` lines
21+
- GHCR + Docker Hub publish workflow (`publish-docker.yml`) with build → smoke test →
22+
integration test → push fail-fast pipeline
23+
- Integration test script (`scripts/integration-test-docker.sh`) that runs a real
24+
opengrep scan and socket-basics CLI scan without requiring API credentials
25+
- Dependabot configuration for Docker images, `app_tests/` Dockerfile, and GitHub Actions
26+
- Buildkite-style dynamic CI pipeline via `scripts/ci_matrix.py` — image and Python
27+
version matrices are now Python-driven, not hardcoded in YAML
28+
- Reusable `_docker-pipeline.yml` workflow as a single lego-brick called by both
29+
`smoke-test.yml` and `publish-docker.yml`
30+
- Floating major version tag automation (`v2` auto-updated on every release)
31+
- OCI image labels baked into published images (`com.socket.trivy-version`, etc.)
32+
- `python:3.12-slim` base image (~850 MB smaller than full)
33+
- Root `.dockerignore` to exclude tests, docs, and artifacts from the build context
34+
- This changelog and automated changelog update workflow
35+
36+
### Changed
37+
- `uv` pinned to `0.10.9` (was `:latest`)
38+
- `smoke-test.yml` restructured as a matrix pipeline driven by `ci_matrix.py`
39+
(previously only tested the main image; `socket-basics-app-tests` will be re-enabled
40+
once its missing source files are committed — see `ci_matrix.py` TODO)
41+
- `smoke-test-docker.sh` gains `--skip-build` and `--check-set` flags for use in CI
42+
pipelines that build separately
43+
44+
---
45+
46+
## [1.1.3] - 2026-03-03
47+
48+
### Added
49+
- Smoke test Docker workflow with scheduled runs every 12 hours ([#41])
50+
- `pytest` GitHub Actions workflow for Python unit tests ([#42])
51+
- Structured findings added to webhook payload ([#38])
52+
53+
### Fixed
54+
- Slack and MS Teams notifiers not reading URL from dashboard config ([#37])
55+
56+
[#37]: https://github.com/SocketDev/socket-basics/pull/37
57+
[#38]: https://github.com/SocketDev/socket-basics/pull/38
58+
[#41]: https://github.com/SocketDev/socket-basics/pull/41
59+
[#42]: https://github.com/SocketDev/socket-basics/pull/42
60+
61+
## [1.1.2] - 2026-03-02
62+
63+
### Changed
64+
- Bump Trivy from `v0.67.2` to `v0.69.2` ([#39])
65+
- `CODEOWNERS` updated with new team name ([#36])
66+
67+
[#36]: https://github.com/SocketDev/socket-basics/pull/36
68+
[#39]: https://github.com/SocketDev/socket-basics/pull/39
69+
70+
## [1.1.1] - 2026-02-26
71+
72+
### Fixed
73+
- Webhook notifier not reading URL from dashboard config ([#34])
74+
- `CODEOWNERS` syntax error ([#35])
75+
76+
[#34]: https://github.com/SocketDev/socket-basics/pull/34
77+
[#35]: https://github.com/SocketDev/socket-basics/pull/35
78+
79+
## [1.1.0] - 2026-02-20
80+
81+
### Fixed
82+
- Jira dashboard config params not reaching notifier ([#22])
83+
- Notifiers reading repo/branch from wrong source ([#30])
84+
- GitHub PR comment enhancement and layout improvements ([#26])
85+
86+
### Changed
87+
- `CODEOWNERS` updated to reference new GHEC team name ([#33])
88+
89+
[#22]: https://github.com/SocketDev/socket-basics/pull/22
90+
[#26]: https://github.com/SocketDev/socket-basics/pull/26
91+
[#30]: https://github.com/SocketDev/socket-basics/pull/30
92+
[#33]: https://github.com/SocketDev/socket-basics/pull/33
93+
94+
## [1.0.29] - 2026-02-19
95+
96+
### Added
97+
- `SKIP_SOCKET_SUBMISSION` and `SKIP_SOCKET_REACH` environment variables for Node.js
98+
Socket CLI integration ([#29])
99+
100+
### Changed
101+
- Pin TruffleHog to known-good version tag ([#32])
102+
- Enrich OpenGrep alerts with full vulnerability metadata and detailed reports ([#28])
103+
104+
[#28]: https://github.com/SocketDev/socket-basics/pull/28
105+
[#29]: https://github.com/SocketDev/socket-basics/pull/29
106+
[#32]: https://github.com/SocketDev/socket-basics/pull/32
107+
108+
## [1.0.28] - 2026-02-06
109+
110+
### Changed
111+
- Dependency upgrades and internal maintenance ([#27])
112+
113+
[#27]: https://github.com/SocketDev/socket-basics/pull/27
114+
115+
## [1.0.27] - 2026-02-06
116+
117+
### Added
118+
- Dockerfile auto-discovery workflow pattern documentation ([#25])
119+
- `scan_type` parameter added to full scan API calls ([#24])
120+
121+
[#24]: https://github.com/SocketDev/socket-basics/pull/24
122+
[#25]: https://github.com/SocketDev/socket-basics/pull/25
123+
124+
## [1.0.26] - 2026-01-20
125+
126+
### Fixed
127+
- Empty CLI string defaults no longer override env/API config ([#17])
128+
129+
### Changed
130+
- Bump `urllib3` from `2.5.0` to `2.6.3` ([#21])
131+
132+
[#17]: https://github.com/SocketDev/socket-basics/pull/17
133+
[#21]: https://github.com/SocketDev/socket-basics/pull/21
134+
135+
## [1.0.25] - 2025-10-28
136+
137+
### Fixed
138+
- Regression in rule name detection ([#15])
139+
140+
[#15]: https://github.com/SocketDev/socket-basics/pull/15
141+
142+
## [1.0.24] - 2025-10-28
143+
144+
### Fixed
145+
- Hard-coded detection for Golang ([#14])
146+
147+
[#14]: https://github.com/SocketDev/socket-basics/pull/14
148+
149+
## [1.0.23] - 2025-10-28
150+
151+
### Changed
152+
- Improve default SAST ruleset ([#13])
153+
154+
[#13]: https://github.com/SocketDev/socket-basics/pull/13
155+
156+
## [1.0.21] - 2025-10-24
157+
158+
### Fixed
159+
- Caching result fix ([#12])
160+
161+
[#12]: https://github.com/SocketDev/socket-basics/pull/12
162+
163+
## [1.0.20] - 2025-10-24
164+
165+
### Fixed
166+
- Restore Node.js and Socket CLI in container ([#11])
167+
168+
[#11]: https://github.com/SocketDev/socket-basics/pull/11
169+
170+
## [1.0.11] - 2025-10-22
171+
172+
### Fixed
173+
- Git detection logic not using `workspace` or `GITHUB_WORKSPACE` correctly ([#10])
174+
175+
[#10]: https://github.com/SocketDev/socket-basics/pull/10
176+
177+
## [1.0.10] - 2025-10-22
178+
179+
### Changed
180+
- Updated examples with PR check and commit hash pinning ([#9])
181+
182+
[#9]: https://github.com/SocketDev/socket-basics/pull/9
183+
184+
## [1.0.9] - 2025-10-22
185+
186+
### Added
187+
- Action inputs for configuring scan behavior ([#8])
188+
189+
### Fixed
190+
- Documentation and version check issues ([#7])
191+
192+
[#7]: https://github.com/SocketDev/socket-basics/pull/7
193+
[#8]: https://github.com/SocketDev/socket-basics/pull/8
194+
195+
## [1.0.3] - 2025-10-21
196+
197+
### Added
198+
- GitHub token support in `action.yml` ([#3])
199+
200+
### Fixed
201+
- `action.yml` configuration issues ([#3])
202+
- Documentation link ([#5])
203+
204+
[#3]: https://github.com/SocketDev/socket-basics/pull/3
205+
[#5]: https://github.com/SocketDev/socket-basics/pull/5
206+
207+
## [1.0.2] - 2025-10-20
208+
209+
### Fixed
210+
- Initial Trivy + Socket results integration fixes ([#2])
211+
212+
[#2]: https://github.com/SocketDev/socket-basics/pull/2
213+
214+
---
215+
216+
<!-- Comparison links — updated automatically by scripts/update_changelog.py on each release -->
217+
[Unreleased]: https://github.com/SocketDev/socket-basics/compare/1.1.3...HEAD
218+
[2.0.0]: https://github.com/SocketDev/socket-basics/compare/1.1.3...v2.0.0
219+
[1.1.3]: https://github.com/SocketDev/socket-basics/compare/1.1.2...1.1.3
220+
[1.1.2]: https://github.com/SocketDev/socket-basics/compare/1.1.1...1.1.2
221+
[1.1.1]: https://github.com/SocketDev/socket-basics/compare/1.1.0...1.1.1
222+
[1.1.0]: https://github.com/SocketDev/socket-basics/compare/1.0.29...1.1.0
223+
[1.0.29]: https://github.com/SocketDev/socket-basics/compare/1.0.28...1.0.29
224+
[1.0.28]: https://github.com/SocketDev/socket-basics/compare/1.0.27...1.0.28
225+
[1.0.27]: https://github.com/SocketDev/socket-basics/compare/1.0.26...1.0.27
226+
[1.0.26]: https://github.com/SocketDev/socket-basics/compare/1.0.25...1.0.26
227+
[1.0.25]: https://github.com/SocketDev/socket-basics/compare/1.0.24...1.0.25
228+
[1.0.24]: https://github.com/SocketDev/socket-basics/compare/1.0.23...1.0.24
229+
[1.0.23]: https://github.com/SocketDev/socket-basics/compare/1.0.21...1.0.23
230+
[1.0.21]: https://github.com/SocketDev/socket-basics/compare/1.0.20...1.0.21
231+
[1.0.20]: https://github.com/SocketDev/socket-basics/compare/1.0.11...1.0.20
232+
[1.0.11]: https://github.com/SocketDev/socket-basics/compare/1.0.10...1.0.11
233+
[1.0.10]: https://github.com/SocketDev/socket-basics/compare/1.0.9...1.0.10
234+
[1.0.9]: https://github.com/SocketDev/socket-basics/compare/1.0.3...1.0.9
235+
[1.0.3]: https://github.com/SocketDev/socket-basics/compare/1.0.2...1.0.3
236+
[1.0.2]: https://github.com/SocketDev/socket-basics/commits/1.0.2

scripts/update_changelog.py

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
#!/usr/bin/env python3
2+
"""
3+
update_changelog.py — Prepend a new release section to CHANGELOG.md.
4+
5+
Called automatically by the publish-docker workflow after a GitHub Release
6+
is created. Reads the generated release notes, inserts a new version section
7+
immediately after [Unreleased], and updates the comparison links at the bottom.
8+
9+
Usage:
10+
# Notes from a file:
11+
python scripts/update_changelog.py --version 2.0.1 --date 2024-06-01 --notes-file notes.txt
12+
13+
# Notes from stdin:
14+
echo "release notes" | python scripts/update_changelog.py --version 2.0.1 --date 2024-06-01
15+
16+
# Dry run (print result without writing):
17+
python scripts/update_changelog.py --version 2.0.1 --date 2024-06-01 --dry-run
18+
"""
19+
from __future__ import annotations
20+
21+
import argparse
22+
import re
23+
import sys
24+
from pathlib import Path
25+
26+
REPO = "SocketDev/socket-basics"
27+
CHANGELOG = Path(__file__).parent.parent / "CHANGELOG.md"
28+
29+
# Tags from v2.0.0 onward use a v prefix; older tags don't.
30+
# The script always adds the v prefix for new releases.
31+
def _tag(version: str) -> str:
32+
"""Return the git tag string for a version (adds v prefix)."""
33+
return f"v{version}"
34+
35+
36+
def _compare_url(from_tag: str, to_tag: str) -> str:
37+
return f"https://github.com/{REPO}/compare/{from_tag}...{to_tag}"
38+
39+
40+
def _commits_url(tag: str) -> str:
41+
return f"https://github.com/{REPO}/commits/{tag}"
42+
43+
44+
def _find_previous_release_tag(content: str) -> str | None:
45+
"""
46+
Find the tag used in the current [Unreleased] comparison link,
47+
which is the tag of the most recently published release.
48+
"""
49+
match = re.search(
50+
r"^\[Unreleased\]:\s+https://github\.com/[^/]+/[^/]+/compare/([^.]+\.[^.]+\.[^.]+)\.\.\.",
51+
content,
52+
re.MULTILINE,
53+
)
54+
return match.group(1) if match else None
55+
56+
57+
def _insert_release_section(content: str, version: str, date: str, notes: str) -> str:
58+
"""
59+
Replace [Unreleased] content with a new ## [version] section.
60+
61+
Clears any manually-maintained [Unreleased] notes (they're superseded by the
62+
GitHub-generated release notes) and inserts the new versioned section.
63+
The [Unreleased] heading is preserved but left empty, ready for the next cycle.
64+
"""
65+
new_section = f"\n## [{version}] - {date}\n\n{notes.strip()}\n"
66+
67+
# Match the [Unreleased] heading through to (but not including) the next ## heading
68+
unreleased_pattern = re.compile(
69+
r"(## \[Unreleased\][^\n]*\n)" # the heading line
70+
r"(.*?)" # any existing [Unreleased] content
71+
r"(?=## \[)", # stop before the next ## [ section
72+
re.IGNORECASE | re.DOTALL,
73+
)
74+
match = unreleased_pattern.search(content)
75+
if not match:
76+
raise ValueError("Could not find '## [Unreleased]' section in CHANGELOG.md")
77+
78+
# Replace the heading + its content with heading (empty) + new versioned section
79+
return content[: match.start()] + match.group(1) + new_section + content[match.end() :]
80+
81+
82+
def _update_links(content: str, version: str, prev_tag: str) -> str:
83+
"""
84+
Update the comparison links block at the bottom of the changelog.
85+
86+
Before:
87+
[Unreleased]: .../compare/1.1.3...HEAD
88+
89+
After publishing v2.0.1:
90+
[Unreleased]: .../compare/v2.0.1...HEAD
91+
[2.0.1]: .../compare/v2.0.0...v2.0.1
92+
"""
93+
new_tag = _tag(version)
94+
95+
# Update the [Unreleased] link to point to the new tag
96+
content = re.sub(
97+
r"^\[Unreleased\]:.*$",
98+
f"[Unreleased]: {_compare_url(new_tag, 'HEAD')}",
99+
content,
100+
flags=re.MULTILINE,
101+
)
102+
103+
# Insert the new version link immediately after [Unreleased]
104+
new_link = f"[{version}]: {_compare_url(prev_tag, new_tag)}"
105+
content = re.sub(
106+
r"(\[Unreleased\]:.*\n)",
107+
rf"\1{new_link}\n",
108+
content,
109+
flags=re.MULTILINE,
110+
)
111+
112+
return content
113+
114+
115+
def main() -> None:
116+
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
117+
parser.add_argument("--version", required=True, help="New version without v prefix, e.g. 2.0.1")
118+
parser.add_argument("--date", required=True, help="Release date in YYYY-MM-DD format")
119+
parser.add_argument("--notes-file", help="Path to file containing release notes (default: read stdin)")
120+
parser.add_argument("--dry-run", action="store_true", help="Print result without writing to disk")
121+
args = parser.parse_args()
122+
123+
# Read release notes
124+
if args.notes_file:
125+
notes = Path(args.notes_file).read_text()
126+
elif not sys.stdin.isatty():
127+
notes = sys.stdin.read()
128+
else:
129+
parser.error("Provide release notes via --notes-file or stdin")
130+
131+
content = CHANGELOG.read_text()
132+
133+
prev_tag = _find_previous_release_tag(content)
134+
if not prev_tag:
135+
raise RuntimeError(
136+
"Could not determine previous release tag from [Unreleased] link in CHANGELOG.md. "
137+
"Ensure the link block at the bottom is up to date."
138+
)
139+
140+
content = _insert_release_section(content, args.version, args.date, notes)
141+
content = _update_links(content, args.version, prev_tag)
142+
143+
if args.dry_run:
144+
print(content)
145+
else:
146+
CHANGELOG.write_text(content)
147+
print(f"CHANGELOG.md updated for {args.version} (previous tag: {prev_tag})")
148+
149+
150+
if __name__ == "__main__":
151+
main()

0 commit comments

Comments
 (0)