diff --git a/.github/release-state.json b/.github/release-state.json new file mode 100644 index 00000000..02115cd4 --- /dev/null +++ b/.github/release-state.json @@ -0,0 +1,5 @@ +{ + "_comment": "Bookkeeping for the release workflows. 'changelog_base' is the commit on develop that the last release covered up to; the next changelog is generated from that commit to develop's tip. Updated automatically by .github/workflows/release-prepare.yml. Edit by hand only to correct a bad range.", + "version": "v0.0.1", + "changelog_base": "45dc95ced4ed422dbbf4494ba44c3cfeb2eeb4ba" +} diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml deleted file mode 100644 index 85dbd98b..00000000 --- a/.github/workflows/release-pr.yml +++ /dev/null @@ -1,114 +0,0 @@ -name: Release PR - -on: - push: - branches: [main] - workflow_dispatch: - inputs: - version: - description: "Override version (e.g. v0.0.3). Leave blank to auto-bump." - required: false - type: string - -permissions: {} - -concurrency: - group: release-pr - cancel-in-progress: false - -jobs: - release-pr: - if: ${{ github.event_name == 'workflow_dispatch' || !contains(github.event.head_commit.message, 'chore(release):') }} - runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - with: - fetch-depth: 0 - fetch-tags: true - persist-credentials: false - - - name: Compute next version - id: version - env: - OVERRIDE: ${{ inputs.version }} - run: | - set -euo pipefail - if [ -n "${OVERRIDE:-}" ]; then - if ! printf '%s' "$OVERRIDE" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then - echo "::error::Invalid version override '$OVERRIDE' (expected vMAJOR.MINOR.PATCH)" - exit 1 - fi - next="$OVERRIDE" - echo "Using override: $next" - else - latest=$(git tag --list 'v*.*.*' --sort=-v:refname | head -n1 || true) - if [ -z "$latest" ]; then - next="v0.0.1" - else - v="${latest#v}" - major="${v%%.*}" - rest="${v#*.}" - minor="${rest%%.*}" - patch="${rest#*.}" - next="v${major}.${minor}.$((patch + 1))" - fi - echo "Latest tag: ${latest:-none}" - fi - echo "next=$next" >> "$GITHUB_OUTPUT" - echo "Next version: $next" - - - name: Ensure changelog exists - run: touch CHANGELOG.md - - - name: Generate changelog - uses: orhun/git-cliff-action@a9a95522b26fe6403f7bb24031f21fb573d0f5ff # v4.9.1 - id: git-cliff - with: - config: cliff.toml - github_token: ${{ secrets.GITHUB_TOKEN }} - args: --unreleased --tag ${{ steps.version.outputs.next }} --prepend CHANGELOG.md - env: - OUTPUT: RELEASE_NOTES.md - - - name: Check for releasable changes - id: check - run: | - set -euo pipefail - if grep -qE '^- ' RELEASE_NOTES.md; then - echo "has_changes=true" >> "$GITHUB_OUTPUT" - echo "Changes found:" - cat RELEASE_NOTES.md - else - echo "has_changes=false" >> "$GITHUB_OUTPUT" - echo "Nothing to release since the last tag. Skipping." - fi - - - name: Write VERSION - if: steps.check.outputs.has_changes == 'true' - env: - NEXT: ${{ steps.version.outputs.next }} - run: printf '%s\n' "$NEXT" > VERSION - - - name: Open release PR - if: steps.check.outputs.has_changes == 'true' - uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7.0.11 - with: - token: ${{ secrets.GITHUB_TOKEN }} - sign-commits: true - base: main - branch: release/${{ steps.version.outputs.next }} - title: "chore(release): ${{ steps.version.outputs.next }}" - commit-message: "chore(release): ${{ steps.version.outputs.next }}" - labels: release - delete-branch: true - add-paths: | - CHANGELOG.md - VERSION - body: | - Automated release PR for **${{ steps.version.outputs.next }}**. - - Review the changelog, edit if needed, then merge. - Merging creates the tag and publishes the GitHub Release. \ No newline at end of file diff --git a/.github/workflows/release-prepare.yml b/.github/workflows/release-prepare.yml new file mode 100644 index 00000000..e2e89763 --- /dev/null +++ b/.github/workflows/release-prepare.yml @@ -0,0 +1,935 @@ +name: Prepare Release + +# Prepares the changelog for the next release. +# +# The changelog is generated from develop, where each commit is a squash-merged PR with a +# title, number, author and labels. main receives only squash commits of develop and does +# not carry this information. +# +# Process: +# 1. Opening the monthly develop -> main PR runs 'build', 'commit' and 'notify'. The new +# CHANGELOG section is committed to release/next as a single signed commit, and a +# link to open the release PR into develop is posted on the monthly PR. The release +# PR is opened manually because the organization does not allow Actions to open PRs. +# 2. While the release PR is open, each push to develop runs 'sync-build' and +# 'sync-commit', which append the new entries to release/next and advance +# changelog_base. Existing entries, including manual edits, are not modified. If no +# prepared release exists on release/next, 'route' runs step 1 instead. +# 3. The release PR is merged into develop immediately before the monthly PR is merged +# into main. release-publish.yml then tags main and publishes the GitHub Release. +# Changes merged into develop between the two merges in step 3 are released in this +# version and listed in the next one. +# +# Versioning: automatic runs propose a patch bump. For a minor or major release, run this +# workflow manually with 'bump' or 'version' before merging the release PR. The run resets +# release/next to develop, discarding manual edits, and renames the release PR. +# +# Security: steps that run git-cliff or process PR titles use a read-only token. Jobs with +# contents: write run only the shell in this file, rebuild VERSION and release-state.json +# themselves, and accept a CHANGELOG.md only if it adds entries to the top section and +# changes nothing else. This workflow does not delete branches. + +on: + pull_request: + # opened, reopened: prepare the release. synchronize (a push to develop): 'route' + # decides between appending to the prepared release and preparing one. + types: [opened, reopened, synchronize] + branches: [main] # base branch; PRs into develop do not trigger this workflow + workflow_dispatch: + inputs: + # Option labels include an example because the dropdown has no per-option description. + # Only the first word is used, so plain values also work through the API. + bump: + description: "How big is this release? Ignored if you set an exact version below." + required: false + default: "patch (e.g. v0.0.3 -> v0.0.4)" + type: choice + options: + - "patch (e.g. v0.0.3 -> v0.0.4)" + - "minor (e.g. v0.0.3 -> v0.1.0)" + - "major (e.g. v0.0.3 -> v1.0.0)" + version: + description: "This is to set an exact version. Setting it overrides the previous choice." + required: false + type: string + pr: + description: "Number of the open develop -> main PR, to comment the release link there." + required: false + type: string + +permissions: {} + +env: + RELEASE_BRANCH: release/next + + # Scripts shared by 'commit' and 'sync-commit'. Environment values are not evaluated as + # expressions, so event data cannot alter the script text. + + # Accepts a rendered CHANGELOG.md only if, relative to the current file, it adds lines + # without removing or changing any; each added line is an entry, a group heading or + # blank; and each non-blank addition is inside the top release section. In 'prepare' + # mode the top heading must be new; in 'sync' mode it must already exist. Added lines + # must not contain <, >, [ or ] outside the generated PR link, which requires + # GITHUB_REPOSITORY in the environment. + # Usage: python3 -c "$CHECK_CHANGELOG" prepare|sync + CHECK_CHANGELOG: | + import os, re, sys + from difflib import SequenceMatcher + + old_path, new_path, mode, version = sys.argv[1:5] + # newline="" preserves \r so that line-ending changes are detected. + with open(old_path, encoding="utf-8", newline="") as f: + old = f.read().split("\n") + with open(new_path, encoding="utf-8", newline="") as f: + new = f.read().split("\n") + + def fail(msg): + sys.exit("::error::Rejected CHANGELOG.md: " + msg) + + h2 = [i for i, line in enumerate(new) if line.startswith("## ")] + if not h2: + fail("it has no release section") + top, end = h2[0], (h2[1] if len(h2) > 1 else len(new)) + if not new[top].startswith("## " + version[1:] + " ("): + fail(f"the top section is {new[top]!r}, not {version}") + + heading = re.compile(r"^## \d+\.\d+\.\d+ \(\d{4}-\d{2}-\d{2}\)$") + shape = re.compile(r"^(### \S.*|- \S.*|)$") + # Release notes are displayed on the site as rendered markdown. Apart from the PR link + # that cliff.toml appends, an added line must not contain anything that can form an + # HTML tag, a markdown link or an image. + pr_link = re.compile( + r" \(\[#(\d+)\]\(https://github\.com/" + re.escape(os.environ["GITHUB_REPOSITORY"]) + r"/pull/\1\)\)", + re.IGNORECASE) + markup = re.compile(r"[<>\[\]]") + added_heading = False + entries = 0 + for op, i1, i2, j1, j2 in SequenceMatcher(None, old, new, autojunk=False).get_opcodes(): + if op == "equal": + continue + if op != "insert": + fail(f"it {op}s existing lines {i1 + 1}-{i2}") + for j in range(j1, j2): + line = new[j] + if j == top: + if mode != "prepare" or not heading.match(line): + fail(f"line {j + 1} adds a release heading: {line!r}") + added_heading = True + continue + if not shape.match(line): + fail(f"line {j + 1} is not an entry or a group heading: {line!r}") + if line and not top < j < end: + fail(f"line {j + 1} is outside the top section") + if markup.search(pr_link.sub("", line)): + fail(f"line {j + 1} contains markup (<, >, [ or ]) outside the PR link: {line!r}") + entries += line.startswith("- ") + + if mode == "prepare" and not added_heading: + fail(f"the {version} heading already existed") + if entries == 0: + fail("it adds no entries") + print(f"CHANGELOG.md accepted: {entries} new entries.") + + # Commits files to a branch with the GraphQL createCommitOnBranch mutation and verifies + # the signature. Commits created through this API are signed by GitHub; a commit made on + # the runner would be unsigned. expectedHeadOid makes the call fail if the branch has + # moved. File contents are passed to jq from disk because CHANGELOG.md exceeds the + # maximum size of a single command-line argument. Writes the commit SHA to + # $GITHUB_OUTPUT as 'oid'. + # Usage: bash -c "$SIGNED_COMMIT" signed-commit =... + SIGNED_COMMIT: | + set -euo pipefail + branch="$1" expected="$2" headline="$3" + shift 3 + : > additions.jsonl + for pair in "$@"; do + path="${pair%%=*}" + file="${pair#*=}" + base64 -w0 "$file" > "$file.b64" + jq -nc --arg path "$path" --rawfile contents "$file.b64" \ + '{path: $path, contents: $contents}' >> additions.jsonl + done + jq -n \ + --arg repo "$GITHUB_REPOSITORY" \ + --arg branch "$branch" \ + --arg oid "$expected" \ + --arg msg "$headline" \ + --slurpfile additions additions.jsonl \ + '{ + query: "mutation($input: CreateCommitOnBranchInput!) { createCommitOnBranch(input: $input) { commit { oid } } }", + variables: { + input: { + branch: { repositoryNameWithOwner: $repo, branchName: $branch }, + expectedHeadOid: $oid, + message: { headline: $msg }, + fileChanges: { additions: $additions } + } + } + }' > commit-payload.json + oid="$(gh api graphql --input commit-payload.json --jq '.data.createCommitOnBranch.commit.oid')" + if [ -z "$oid" ]; then + echo "::error::createCommitOnBranch returned no commit." + exit 1 + fi + # The signature is verified here because branch protection would otherwise reject an + # unsigned commit later, with a less specific error. + verified="$(gh api "repos/${GITHUB_REPOSITORY}/commits/${oid}" --jq '.commit.verification.verified')" + if [ "$verified" != "true" ]; then + echo "::error::Commit ${oid} is not signed. Release commits must be signed." + exit 1 + fi + echo "Signed commit ${oid} on ${branch}." + echo "oid=${oid}" >> "$GITHUB_OUTPUT" + +jobs: + # --------------------------------------------------------------------------------------- + # Route: selects the action for this event. Opening or reopening the monthly PR, and + # manual runs, prepare a release. A push to develop appends to the prepared release on + # release/next; if none exists (a failed prepare, or a PR opened with a merge conflict, + # for which GitHub runs no workflows), it prepares one instead. + # --------------------------------------------------------------------------------------- + + route: + if: >- + github.event_name == 'workflow_dispatch' || + (github.event.pull_request.base.ref == 'main' && + github.event.pull_request.head.ref == 'develop' && + github.event.pull_request.head.repo.full_name == github.repository) + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + contents: read + outputs: + mode: ${{ steps.route.outputs.mode }} + version: ${{ steps.route.outputs.version }} + base: ${{ steps.route.outputs.base }} + head: ${{ steps.route.outputs.head }} + branch_sha: ${{ steps.route.outputs.branch_sha }} + steps: + - name: Decide between prepare and sync + id: route + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + EVENT: ${{ github.event_name }} + ACTION: ${{ github.event.action }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + run: | + set -euo pipefail + if [ "$EVENT" = "workflow_dispatch" ] || [ "$ACTION" != "synchronize" ]; then + echo "Monthly PR ${ACTION:-} / manual run: prepare." + echo "mode=prepare" >> "$GITHUB_OUTPUT" + exit 0 + fi + + # gh api writes the JSON error body to stdout on HTTP errors, including with --jq, so + # both the exit status and the body are checked. Only 404 is treated as "not found"; + # any other error fails the job. + # Usage: get [gh args]; returns 1 on 404. + get() { + local path="$1" out="$2" + shift 2 + if gh api "$@" "repos/${GITHUB_REPOSITORY}/${path}" > "$out" 2>/dev/null; then + return 0 + elif jq -e '.status == "404"' "$out" >/dev/null 2>&1; then + return 1 + fi + echo "::error::GitHub API call failed for ${path}: $(cat "$out")" + exit 1 + } + file_at() { get "contents/$1?ref=$2" "$3" -H "Accept: application/vnd.github.raw"; } + tagged() { get "git/ref/tags/$1" tag.json; } + + # 1. The release PR is merged into develop and awaits publication. Changes pushed now + # are released in that version and listed in the next one. + if ! file_at .github/release-state.json "$HEAD_SHA" develop-state.json; then + echo "::error::develop has no .github/release-state.json." + exit 1 + fi + develop_version="$(jq -r '.version // empty' develop-state.json)" + if [ -n "$develop_version" ] && ! tagged "$develop_version"; then + echo "The ${develop_version} release PR is already merged into develop." + echo "Anything pushed from now on ships in ${develop_version} but is listed in the next release." + echo "mode=none" >> "$GITHUB_OUTPUT" + exit 0 + fi + + # 2. No prepared release on release/next: prepare one. + if ! get "git/ref/heads/${RELEASE_BRANCH}" branch.json; then + echo "No ${RELEASE_BRANCH} branch: nothing was prepared for this PR yet. Preparing now." + echo "mode=prepare" >> "$GITHUB_OUTPUT" + exit 0 + fi + branch_sha="$(jq -r '.object.sha // empty' branch.json)" + if ! printf '%s' "$branch_sha" | grep -qE '^[0-9a-f]{40}$'; then + echo "::error::Unexpected ${RELEASE_BRANCH} ref: '${branch_sha}'." + exit 1 + fi + if ! file_at .github/release-state.json "$branch_sha" branch-state.json; then + echo "::error::${RELEASE_BRANCH} has no .github/release-state.json." + exit 1 + fi + version="$(jq -r '.version // empty' branch-state.json)" + base="$(jq -r '.changelog_base // empty' branch-state.json)" + if ! printf '%s' "$version" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$' \ + || ! printf '%s' "$base" | grep -qE '^[0-9a-f]{40}$'; then + echo "::error::${RELEASE_BRANCH} has an unreadable release-state.json." + exit 1 + fi + # This also covers a prepare that failed after resetting the branch, which then + # carries develop's state and therefore the last published version. + if tagged "$version"; then + echo "${RELEASE_BRANCH} holds ${version}, which is already published. Preparing the next release." + echo "mode=prepare" >> "$GITHUB_OUTPUT" + exit 0 + fi + + # 3. A prepared release is pending: append the new entries to it. + if [ "$base" = "$HEAD_SHA" ]; then + echo "${RELEASE_BRANCH} already covers develop. Nothing to sync." + echo "mode=none" >> "$GITHUB_OUTPUT" + exit 0 + fi + echo "Syncing ${version} on ${RELEASE_BRANCH}: ${base}..${HEAD_SHA}" + { + echo "mode=sync" + echo "version=$version" + echo "base=$base" + echo "head=$HEAD_SHA" + echo "branch_sha=$branch_sha" + } >> "$GITHUB_OUTPUT" + + # --------------------------------------------------------------------------------------- + # Prepare: builds the release and commits it to release/next. + # --------------------------------------------------------------------------------------- + + build: + needs: route + if: needs.route.outputs.mode == 'prepare' + runs-on: ubuntu-latest + timeout-minutes: 10 + concurrency: + group: release-prepare + cancel-in-progress: false + # Read-only token: this job runs git-cliff and processes PR titles. + permissions: + contents: read + pull-requests: read + outputs: + next: ${{ steps.version.outputs.next }} + head_sha: ${{ steps.range.outputs.head_sha }} + has_changes: ${{ steps.check.outputs.has_changes }} + notes_b64: ${{ steps.out.outputs.notes_b64 }} + changelog_b64: ${{ steps.out.outputs.changelog_b64 }} + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + # The develop commit of the triggering event; the develop tip on manual runs. + ref: ${{ github.event.pull_request.head.sha || 'develop' }} + fetch-depth: 0 + fetch-tags: true + persist-credentials: false + + # Stops if a prepared release has not been published. A version recorded in + # release-state.json is published once release-publish.yml has tagged it. An untagged + # version means its chore(release) commit is on develop but not yet on main; preparing + # again would produce a near-empty range and a duplicate section. + # + # There is no override. Both resolutions listed below correct the state, after which + # this check passes. + - name: Guard against an unpublished release + run: | + set -euo pipefail + prepared="" + if [ -f .github/release-state.json ]; then + prepared="$(jq -r '.version // empty' .github/release-state.json)" + fi + if [ -z "$prepared" ]; then + echo "No version recorded yet. Continuing." + exit 0 + fi + if git rev-parse -q --verify "refs/tags/${prepared}" >/dev/null; then + echo "Last recorded release ${prepared} is published. Continuing." + exit 0 + fi + echo "::error::${prepared} is already prepared on develop but has no tag yet." + echo "" + echo "That means ${prepared}'s chore(release) commit reached develop, but develop" + echo "has not reached main yet, so release-publish.yml never tagged it." + echo "" + echo "To publish ${prepared} (what you normally want):" + echo " merge the monthly develop -> main PR, then run this workflow again." + echo "" + echo "To throw ${prepared} away and prepare a different version instead:" + echo " revert its chore(release) commit on develop, then run this workflow again." + echo " The revert restores the previous version in release-state.json, which is" + echo " tagged, so this check passes." + exit 1 + + - name: Compute next version + id: version + env: + OVERRIDE: ${{ inputs.version }} + BUMP: ${{ inputs.bump }} + run: | + set -euo pipefail + if [ -n "${OVERRIDE:-}" ]; then + if ! printf '%s' "$OVERRIDE" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then + echo "::error::Invalid version override '$OVERRIDE' (expected vMAJOR.MINOR.PATCH)" + exit 1 + fi + next="$OVERRIDE" + echo "Using exact override: $next" + else + # Dropdown values include an example; only the first word is used. + kind="${BUMP:-patch}" + kind="${kind%% *}" + # Only strict vMAJOR.MINOR.PATCH tags are considered; the glob also matches names such + # as v1.2.3-rc1. awk is used because grep exits 1 when nothing matches, which fails + # under pipefail. + latest=$(git tag --list 'v*.*.*' --sort=-v:refname \ + | awk '/^v[0-9]+\.[0-9]+\.[0-9]+$/ { print; exit }') + if [ -z "$latest" ]; then + next="v0.0.1" + else + v="${latest#v}" + major="${v%%.*}" + rest="${v#*.}" + minor="${rest%%.*}" + patch="${rest#*.}" + case "$kind" in + major) next="v$((major + 1)).0.0" ;; + minor) next="v${major}.$((minor + 1)).0" ;; + patch) next="v${major}.${minor}.$((patch + 1))" ;; + *) echo "::error::Invalid bump '${BUMP}' (expected patch, minor or major)"; exit 1 ;; + esac + fi + echo "Latest tag: ${latest:-none}, bump: ${kind}" + fi + # Validated on every path: the action passes the value unquoted to git-cliff. + if ! printf '%s' "$next" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then + echo "::error::Computed version '$next' is not vMAJOR.MINOR.PATCH." + exit 1 + fi + if git rev-parse -q --verify "refs/tags/${next}" >/dev/null; then + echo "::error::Tag ${next} already exists. Pick a different version." + exit 1 + fi + echo "next=$next" >> "$GITHUB_OUTPUT" + echo "Next version: $next" + + - name: Resolve changelog range + id: range + run: | + set -euo pipefail + head_sha="$(git rev-parse HEAD)" + base="" + if [ -f .github/release-state.json ]; then + base="$(jq -r '.changelog_base // empty' .github/release-state.json)" + fi + + if [ -z "$base" ]; then + echo "::warning::No changelog_base in .github/release-state.json, using full history." + range="$head_sha" + elif ! printf '%s' "$base" | grep -qE '^[0-9a-f]{40}$'; then + echo "::error::changelog_base '$base' is not a full commit SHA. Fix .github/release-state.json." + exit 1 + elif ! git cat-file -e "${base}^{commit}" 2>/dev/null; then + echo "::error::changelog_base '$base' is not a commit reachable from develop." + exit 1 + elif ! git merge-base --is-ancestor "$base" HEAD; then + echo "::error::changelog_base '$base' is not an ancestor of develop. Fix .github/release-state.json." + exit 1 + else + range="${base}..${head_sha}" + fi + + count="$(git rev-list --count "$range")" + echo "Range: $range ($count commits)" + echo "range=$range" >> "$GITHUB_OUTPUT" + echo "head_sha=$head_sha" >> "$GITHUB_OUTPUT" + echo "count=$count" >> "$GITHUB_OUTPUT" + + - name: Report nothing to release + if: steps.range.outputs.count == '0' + run: | + echo "No commits on develop since the last release." + echo "No commits on develop since the last release." >> "$GITHUB_STEP_SUMMARY" + + - name: Generate changelog + if: steps.range.outputs.count != '0' + uses: orhun/git-cliff-action@f50e11560dce63f7c33227798f90b924471a88b5 # v4.8.0 + with: + config: cliff.toml + github_token: ${{ secrets.GITHUB_TOKEN }} + args: ${{ steps.range.outputs.range }} --tag ${{ steps.version.outputs.next }} + env: + OUTPUT: RELEASE_FULL.md + # The checkout is a detached HEAD, from which git-cliff cannot infer the GitHub + # repository. Without this variable it skips the GitHub lookup, and entries lack PR + # links, authors and label groups. + GITHUB_REPO: ${{ github.repository }} + + - name: Check for releasable entries + if: steps.range.outputs.count != '0' + id: check + run: | + set -euo pipefail + # Keep only the version section; git-cliff also emits the configured header. + # --prepend is not used because it writes the header again on every run. + sed -n '/^## /,$p' RELEASE_FULL.md > RELEASE_NOTES.md + if grep -qE '^- ' RELEASE_NOTES.md; then + echo "has_changes=true" >> "$GITHUB_OUTPUT" + echo "Changes found:" + cat RELEASE_NOTES.md + else + echo "has_changes=false" >> "$GITHUB_OUTPUT" + echo "Every commit in range was filtered out (dependencies, release chores). Skipping." + echo "Every commit since the last release is filtered out by cliff.toml. Nothing to release." >> "$GITHUB_STEP_SUMMARY" + fi + + - name: Splice the new section into CHANGELOG.md + if: steps.check.outputs.has_changes == 'true' + run: | + set -euo pipefail + touch CHANGELOG.md + first="$(grep -n '^## ' CHANGELOG.md | head -n1 | cut -d: -f1 || true)" + if [ -n "$first" ]; then + # Insert above the previous release, below the existing header. The added blank line + # separates the new section from the next heading. + head -n "$((first - 1))" CHANGELOG.md > CHANGELOG.new + cat RELEASE_NOTES.md >> CHANGELOG.new + printf '\n' >> CHANGELOG.new + tail -n "+${first}" CHANGELOG.md >> CHANGELOG.new + else + # No previous release: git-cliff's output already includes the header. + cp RELEASE_FULL.md CHANGELOG.new + fi + mv CHANGELOG.new CHANGELOG.md + head -n 12 CHANGELOG.md + + # Job outputs are the only data passed to the write job. Base64 keeps each value on one + # line; the commit job validates everything it receives. + - name: Hand the result to the commit job + if: steps.check.outputs.has_changes == 'true' + id: out + run: | + set -euo pipefail + echo "notes_b64=$(base64 -w0 RELEASE_NOTES.md)" >> "$GITHUB_OUTPUT" + echo "changelog_b64=$(base64 -w0 CHANGELOG.md)" >> "$GITHUB_OUTPUT" + + commit: + needs: build + if: needs.build.outputs.has_changes == 'true' + runs-on: ubuntu-latest + timeout-minutes: 10 + concurrency: + group: release-branch-prepare + cancel-in-progress: false + # No checkout and no third-party actions: only the shell below runs with the write + # token. + permissions: + contents: write + outputs: + oid: ${{ steps.push.outputs.oid }} + steps: + - name: Check the build output and rebuild VERSION and state + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NEXT: ${{ needs.build.outputs.next }} + HEAD_SHA: ${{ needs.build.outputs.head_sha }} + CHANGELOG_B64: ${{ needs.build.outputs.changelog_b64 }} + run: | + set -euo pipefail + if ! printf '%s' "$NEXT" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then + echo "::error::Invalid version '$NEXT' from build." + exit 1 + fi + if ! printf '%s' "$HEAD_SHA" | grep -qE '^[0-9a-f]{40}$'; then + echo "::error::Invalid commit '$HEAD_SHA' from build." + exit 1 + fi + if gh api "repos/${GITHUB_REPOSITORY}/git/ref/tags/${NEXT}" >/dev/null 2>&1; then + echo "::error::Tag ${NEXT} already exists." + exit 1 + fi + # The release branch must start from a commit on develop. + status="$(gh api "repos/${GITHUB_REPOSITORY}/compare/${HEAD_SHA}...develop" --jq '.status')" + case "$status" in + identical | ahead) : ;; + *) echo "::error::${HEAD_SHA} is not on develop (compare status: ${status})."; exit 1 ;; + esac + + # Current files are read from GitHub, not taken from the build job. + gh api -H "Accept: application/vnd.github.raw" \ + "repos/${GITHUB_REPOSITORY}/contents/CHANGELOG.md?ref=${HEAD_SHA}" > CHANGELOG.current.md + gh api -H "Accept: application/vnd.github.raw" \ + "repos/${GITHUB_REPOSITORY}/contents/.github/release-state.json?ref=${HEAD_SHA}" > state.current.json + + printf '%s' "$CHANGELOG_B64" | base64 -d > CHANGELOG.md + python3 -c "$CHECK_CHANGELOG" CHANGELOG.current.md CHANGELOG.md prepare "$NEXT" + + printf '%s\n' "$NEXT" > VERSION + jq --arg v "$NEXT" --arg b "$HEAD_SHA" \ + '.version = $v | .changelog_base = $b' state.current.json > release-state.json + cat release-state.json + + - name: Push release branch + id: push + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NEXT: ${{ needs.build.outputs.next }} + HEAD_SHA: ${{ needs.build.outputs.head_sha }} + run: | + set -euo pipefail + # createCommitOnBranch requires an existing branch, so release/next is first pointed at + # the develop commit. The update is forced: every prepare starts from develop. + if gh api "repos/${GITHUB_REPOSITORY}/git/ref/heads/${RELEASE_BRANCH}" >/dev/null 2>&1; then + gh api -X PATCH "repos/${GITHUB_REPOSITORY}/git/refs/heads/${RELEASE_BRANCH}" \ + -f sha="$HEAD_SHA" -F force=true >/dev/null + echo "Reset ${RELEASE_BRANCH} to ${HEAD_SHA}." + else + gh api -X POST "repos/${GITHUB_REPOSITORY}/git/refs" \ + -f ref="refs/heads/${RELEASE_BRANCH}" -f sha="$HEAD_SHA" >/dev/null + echo "Created ${RELEASE_BRANCH} at ${HEAD_SHA}." + fi + + # If a sync-commit lands between the reset and this commit, expectedHeadOid makes this + # step fail. Re-run the workflow in that case. + bash -c "$SIGNED_COMMIT" signed-commit "$RELEASE_BRANCH" "$HEAD_SHA" "chore(release): ${NEXT}" \ + CHANGELOG.md=CHANGELOG.md \ + VERSION=VERSION \ + .github/release-state.json=release-state.json + + notify: + needs: [build, commit] + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + pull-requests: write + steps: + - name: Link, rename and comment + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NEXT: ${{ needs.build.outputs.next }} + NOTES_B64: ${{ needs.build.outputs.notes_b64 }} + COMMIT_OID: ${{ needs.commit.outputs.oid }} + PR: ${{ github.event.pull_request.number || inputs.pr }} + run: | + set -euo pipefail + if ! printf '%s' "$NEXT" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then + echo "::error::Invalid version '$NEXT' from build." + exit 1 + fi + if ! printf '%s' "$COMMIT_OID" | grep -qE '^[0-9a-f]{40}$'; then + echo "::error::Invalid commit '$COMMIT_OID' from commit." + exit 1 + fi + # 'pr' is free text on manual runs and is used in an API path. + if [ -n "${PR:-}" ] && ! printf '%s' "$PR" | grep -qE '^[0-9]+$'; then + echo "::error::Invalid PR number '$PR'." + exit 1 + fi + printf '%s' "$NOTES_B64" | base64 -d > RELEASE_NOTES.md + + title="chore(release): ${NEXT}" + + # A re-run resets release/next, which updates an open release PR in place; the PR is + # renamed to the new version. The organization restricts creating PRs, not editing them. + # + # --head matches the branch name only and therefore also returns PRs from forks. Only a + # PR from this repository whose head is the commit created by the commit job is treated + # as the release PR. Other PRs are ignored. + gh pr list --repo "$GITHUB_REPOSITORY" --head "$RELEASE_BRANCH" --base develop --state open \ + --json number,isCrossRepository,headRepository,headRepositoryOwner,headRefOid > prs.json + release_pr="$(jq -r --arg repo "$GITHUB_REPOSITORY" --arg oid "$COMMIT_OID" ' + [ .[] + | select(.isCrossRepository == false + and ((.headRepositoryOwner.login + "/" + .headRepository.name) | ascii_downcase) == ($repo | ascii_downcase) + and .headRefOid == $oid) + | .number ] | first // empty' prs.json)" + ignored="$(jq -r --arg n "$release_pr" '[.[] | select((.number | tostring) != $n) | "#\(.number)"] | join(", ")' prs.json)" + if [ -n "$ignored" ]; then + echo "::warning::Ignored ${ignored}: open PRs from a branch named ${RELEASE_BRANCH} that are not this repository's release branch at ${COMMIT_OID}." + fi + if [ -n "$release_pr" ]; then + if gh api -X PATCH "repos/${GITHUB_REPOSITORY}/pulls/${release_pr}" -f title="$title" >/dev/null; then + echo "Renamed release PR #${release_pr} to '${title}'." + else + echo "::warning::Could not rename release PR #${release_pr}. Set its title to '${title}' by hand." + fi + action="The open release PR #${release_pr} was updated in place and renamed to \`${title}\`." + else + body="$(printf '%s\n' \ + "Changelog for **${NEXT}**, generated from develop's history by \`release-prepare.yml\`." \ + "" \ + "**Merge order.** Merge this PR into \`develop\` last, immediately before the monthly \`develop\` -> \`main\` PR." \ + "\`main\` picks up the changelog inside that squash commit, and \`release-publish.yml\` tags it and cuts the GitHub Release." \ + "" \ + "**Keeping up with develop.** Until this PR is merged, every push to \`develop\` appends its new entries to this branch automatically." \ + "Anything merged into \`develop\` after this PR and before the monthly PR still ships in ${NEXT}, but is listed in the next release." \ + "" \ + "**Version.** \`${NEXT}\` is an automatic patch bump. For a minor or major, re-run the **Prepare Release** workflow with the \`bump\` input before merging." \ + "That resets this branch to \`develop\` (edits made here are lost) and renames this PR. Do not edit \`VERSION\` by hand." \ + "" \ + "Wording of the entries is safe to edit here.")" + enc_title="$(jq -rn --arg s "$title" '$s|@uri')" + enc_body="$(jq -rn --arg s "$body" '$s|@uri')" + url="https://github.com/${GITHUB_REPOSITORY}/compare/develop...${RELEASE_BRANCH}?quick_pull=1&labels=release&title=${enc_title}&body=${enc_body}" + action="[**Open the release PR into \`develop\`**](${url}) (title, body and \`release\` label are prefilled)." + fi + + { + echo "## Release ${NEXT} is ready" + echo "" + echo "$action" + echo "" + echo "
Changelog preview" + echo "" + cat RELEASE_NOTES.md + echo "" + echo "
" + } >> "$GITHUB_STEP_SUMMARY" + + if [ -z "${PR:-}" ]; then + echo "No monthly PR to comment on. The link is in the job summary." + exit 0 + fi + { + echo "" + echo "### Release \`${NEXT}\` is ready" + echo "" + echo "$action" + echo "" + echo "Merge the release PR into \`develop\` last, immediately before this PR. Tagging and the GitHub Release happen automatically once \`main\` has the new \`VERSION\`." + echo "" + echo "\`${NEXT}\` is an automatic patch bump. For a minor or major, re-run **Prepare Release** with the \`bump\` input before merging the release PR." + echo "" + echo "
Changelog preview" + echo "" + cat RELEASE_NOTES.md + echo "" + echo "
" + } > comment.md + + # The comment is located by its marker rather than with `gh pr comment --edit-last`, + # which edits the actor's most recent comment. The marker must start the body and the + # author must be this bot. + id="$(gh api "repos/${GITHUB_REPOSITORY}/issues/${PR}/comments" --paginate \ + --jq '[.[] | select(.user.login == "github-actions[bot]" and (.body | startswith(""))) | .id] | last // empty' \ + | tail -n1)" + if [ -n "$id" ]; then + gh api -X PATCH "repos/${GITHUB_REPOSITORY}/issues/comments/${id}" \ + -F body=@comment.md >/dev/null + echo "Updated release comment ${id}." + else + gh api -X POST "repos/${GITHUB_REPOSITORY}/issues/${PR}/comments" \ + -F body=@comment.md >/dev/null + echo "Posted a new release comment." + fi + + # --------------------------------------------------------------------------------------- + # Sync: runs on a push to develop while a prepared release is pending on release/next + # (see 'route') and appends the new entries to it. Posts no comments. + # --------------------------------------------------------------------------------------- + + sync-build: + needs: route + if: needs.route.outputs.mode == 'sync' + runs-on: ubuntu-latest + timeout-minutes: 10 + concurrency: + # Only the latest push is relevant: each run covers everything since the branch's + # changelog_base, and sync-commit does not commit over a branch that has moved. + group: release-sync-${{ github.event.pull_request.number }} + cancel-in-progress: true + # Read-only token: this job runs git-cliff and processes PR titles. + permissions: + contents: read + pull-requests: read + outputs: + has_entries: ${{ steps.merge.outputs.has_entries }} + version: ${{ needs.route.outputs.version }} + old_base: ${{ needs.route.outputs.base }} + new_base: ${{ needs.route.outputs.head }} + branch_sha: ${{ needs.route.outputs.branch_sha }} + changelog_b64: ${{ steps.merge.outputs.changelog_b64 }} + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + persist-credentials: false + + # 'route' validated the formats; the ancestry check requires the checkout. + - name: Check the range + env: + VERSION_TO_SYNC: ${{ needs.route.outputs.version }} + BASE: ${{ needs.route.outputs.base }} + run: | + set -euo pipefail + if ! git merge-base --is-ancestor "$BASE" HEAD; then + echo "::error::changelog_base ${BASE} on ${RELEASE_BRANCH} is not an ancestor of develop." + exit 1 + fi + echo "Syncing ${VERSION_TO_SYNC}: $(git rev-list --count "${BASE}..HEAD") new commit(s) since ${BASE}." + + - name: Render the new entries + uses: orhun/git-cliff-action@f50e11560dce63f7c33227798f90b924471a88b5 # v4.8.0 + with: + config: cliff.toml + github_token: ${{ secrets.GITHUB_TOKEN }} + args: ${{ needs.route.outputs.base }}..${{ needs.route.outputs.head }} --tag ${{ needs.route.outputs.version }} + env: + OUTPUT: SYNC_FULL.md + # Detached HEAD: see "Generate changelog" in the build job. + GITHUB_REPO: ${{ github.repository }} + + - name: Append them to the release branch's changelog + id: merge + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BRANCH_SHA: ${{ needs.route.outputs.branch_sha }} + run: | + set -euo pipefail + gh api -H "Accept: application/vnd.github.raw" \ + "repos/${GITHUB_REPOSITORY}/contents/CHANGELOG.md?ref=${BRANCH_SHA}" > CHANGELOG.branch.md + + # Appends each new entry to the end of its group in the top section, adding the group + # heading in cliff.toml order where missing. Existing lines, including manual edits, are + # not modified. Entries whose PR is already linked in the section are skipped. + python3 - CHANGELOG.branch.md SYNC_FULL.md cliff.toml CHANGELOG.md <<'PY' + import re, sys + + branch_path, notes_path, config_path, out_path = sys.argv[1:5] + with open(branch_path, encoding="utf-8", newline="") as f: + lines = f.read().split("\n") + with open(notes_path, encoding="utf-8") as f: + notes = f.read().split("\n") + with open(config_path, encoding="utf-8") as f: + config = f.read() + + order = [name for _, name in sorted( + (int(n), name.strip()) for n, name in re.findall(r'group = "([^"]+)"', config))] + rank = lambda g: order.index(g) if g in order else len(order) + + new, group = {}, None + for line in notes: + if line.startswith("### "): + group = line[4:].strip() + new.setdefault(group, []) + elif line.startswith("- ") and group: + new[group].append(line) + + def section(): + h2 = [i for i, l in enumerate(lines) if l.startswith("## ")] + return h2[0], (h2[1] if len(h2) > 1 else len(lines)) + + added = 0 + for group in sorted(new, key=rank): + start, end = section() + text = "\n".join(lines[start:end]) + entries = [] + for e in new[group]: + m = re.search(r"/pull/\d+\)", e) + if not (m and m.group(0) in text): + entries.append(e) + if not entries: + continue + heading = next((i for i in range(start + 1, end) if lines[i] == "### " + group), None) + if heading is not None: + last, i = heading, heading + 1 + while i < end and not lines[i].startswith("### "): + if lines[i].startswith("- "): + last = i + i += 1 + if last == heading: + lines[heading + 1:heading + 1] = [""] + entries + else: + lines[last + 1:last + 1] = entries + else: + at = next((i for i in range(start + 1, end) + if lines[i].startswith("### ") and rank(lines[i][4:].strip()) > rank(group)), end) + lines[at:at] = ["### " + group, ""] + entries + [""] + added += len(entries) + + with open(out_path, "w", encoding="utf-8", newline="") as f: + f.write("\n".join(lines)) + print(f"{added} new entries.") + PY + + if cmp -s CHANGELOG.branch.md CHANGELOG.md; then + echo "Nothing new to list: everything since the last sync is filtered out or already there." + exit 0 + fi + diff CHANGELOG.branch.md CHANGELOG.md || true + echo "has_entries=true" >> "$GITHUB_OUTPUT" + echo "changelog_b64=$(base64 -w0 CHANGELOG.md)" >> "$GITHUB_OUTPUT" + + sync-commit: + needs: sync-build + if: needs.sync-build.outputs.has_entries == 'true' + runs-on: ubuntu-latest + timeout-minutes: 10 + concurrency: + group: release-branch-sync + cancel-in-progress: false + # No checkout and no third-party actions: only the shell below runs with the write + # token. + permissions: + contents: write + steps: + - name: Check the build output and commit it + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + RELEASE_VERSION: ${{ needs.sync-build.outputs.version }} + OLD_BASE: ${{ needs.sync-build.outputs.old_base }} + NEW_BASE: ${{ needs.sync-build.outputs.new_base }} + BRANCH_SHA: ${{ needs.sync-build.outputs.branch_sha }} + CHANGELOG_B64: ${{ needs.sync-build.outputs.changelog_b64 }} + run: | + set -euo pipefail + if ! printf '%s' "$RELEASE_VERSION" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then + echo "::error::Invalid version '$RELEASE_VERSION' from sync-build." + exit 1 + fi + for sha in "$OLD_BASE" "$NEW_BASE" "$BRANCH_SHA"; do + if ! printf '%s' "$sha" | grep -qE '^[0-9a-f]{40}$'; then + echo "::error::Invalid commit '$sha' from sync-build." + exit 1 + fi + done + + # The new base must be on develop and after the old base. + status="$(gh api "repos/${GITHUB_REPOSITORY}/compare/${NEW_BASE}...develop" --jq '.status')" + case "$status" in + identical | ahead) : ;; + *) echo "::error::${NEW_BASE} is not on develop (compare status: ${status})."; exit 1 ;; + esac + status="$(gh api "repos/${GITHUB_REPOSITORY}/compare/${OLD_BASE}...${NEW_BASE}" --jq '.status')" + if [ "$status" != "ahead" ]; then + echo "::error::${NEW_BASE} does not come after ${OLD_BASE} (compare status: ${status})." + exit 1 + fi + + # Current files are read from GitHub, not taken from the build job. + gh api -H "Accept: application/vnd.github.raw" \ + "repos/${GITHUB_REPOSITORY}/contents/CHANGELOG.md?ref=${BRANCH_SHA}" > CHANGELOG.current.md + gh api -H "Accept: application/vnd.github.raw" \ + "repos/${GITHUB_REPOSITORY}/contents/.github/release-state.json?ref=${BRANCH_SHA}" > state.current.json + if [ "$(jq -r '.version' state.current.json)" != "$RELEASE_VERSION" ] \ + || [ "$(jq -r '.changelog_base' state.current.json)" != "$OLD_BASE" ]; then + echo "::error::${RELEASE_BRANCH} at ${BRANCH_SHA} does not hold what sync-build read." + exit 1 + fi + + printf '%s' "$CHANGELOG_B64" | base64 -d > CHANGELOG.md + python3 -c "$CHECK_CHANGELOG" CHANGELOG.current.md CHANGELOG.md sync "$RELEASE_VERSION" + + jq --arg b "$NEW_BASE" '.changelog_base = $b' state.current.json > release-state.json + + # expectedHeadOid is the branch tip read by sync-build. If the branch has moved since + # (another sync, a prepare re-run, a manual edit), the commit fails and the next push to + # develop retries. + bash -c "$SIGNED_COMMIT" signed-commit "$RELEASE_BRANCH" "$BRANCH_SHA" "chore(release): add new develop entries to ${RELEASE_VERSION}" \ + CHANGELOG.md=CHANGELOG.md \ + .github/release-state.json=release-state.json diff --git a/.github/workflows/release-publish.yml b/.github/workflows/release-publish.yml index c1209cd8..3c70df82 100644 --- a/.github/workflows/release-publish.yml +++ b/.github/workflows/release-publish.yml @@ -1,61 +1,153 @@ name: Publish Release +# Tags main and publishes the GitHub Release when main carries a VERSION that has not +# been published. +# +# Runs on every push to main and reads VERSION, so it covers every way main can change. +# The job is idempotent: it creates only what is missing and exits when the version is +# already published. + on: - pull_request: - types: [closed] + push: + branches: [main] + workflow_dispatch: permissions: {} +concurrency: + group: publish-release + cancel-in-progress: false + jobs: publish: - if: > - github.event.pull_request.merged == true && - github.event.pull_request.base.ref == 'main' && - startsWith(github.event.pull_request.head.ref, 'release/') && - contains(github.event.pull_request.labels.*.name, 'release') + # Manual runs can be started from any branch; only main is released. + if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest + timeout-minutes: 10 permissions: contents: write steps: + # The commit that triggered the run, not the current tip of main. - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: - ref: main + ref: ${{ github.sha }} fetch-depth: 0 + fetch-tags: true persist-credentials: false - name: Read version id: version run: | set -euo pipefail + if [ ! -f VERSION ]; then + echo "::error::No VERSION file on main." + exit 1 + fi tag="$(head -n1 VERSION | tr -d '[:space:]')" if ! printf '%s' "$tag" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then echo "::error::Invalid VERSION content '$tag' (expected vMAJOR.MINOR.PATCH)" exit 1 fi + # The release commit is the one that last changed VERSION on main (the monthly squash), + # not HEAD, so a retried or delayed run tags the correct commit. + release_sha="$(git log -1 --format=%H -- VERSION)" echo "tag=$tag" >> "$GITHUB_OUTPUT" + echo "release_sha=$release_sha" >> "$GITHUB_OUTPUT" + echo "VERSION on main: $tag, set by ${release_sha}" + + # Most pushes to main do not change the version, so an existing tag is the normal case. + # Tag and release are checked separately so that a run that tagged but failed before + # publishing can be completed by a re-run. + - name: Work out what is missing + id: state + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG: ${{ steps.version.outputs.tag }} + RELEASE_SHA: ${{ steps.version.outputs.release_sha }} + run: | + set -euo pipefail + + if git rev-parse -q --verify "refs/tags/${TAG}" >/dev/null; then + # An existing tag is accepted only if it points at the release commit; otherwise a + # tag created on an unreviewed commit could be published. + tagged="$(git rev-parse "refs/tags/${TAG}^{commit}")" + if [ "$tagged" != "$RELEASE_SHA" ]; then + echo "::error::Tag ${TAG} points at ${tagged}, but the release commit is ${RELEASE_SHA}." + echo "Refusing to publish on a tag this workflow did not create. Inspect and delete the tag by hand." + exit 1 + fi + need_tag=false + else + need_tag=true + fi - - name: Extract latest changelog section + if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then + need_release=false + else + need_release=true + fi + + echo "need_tag=$need_tag" >> "$GITHUB_OUTPUT" + echo "need_release=$need_release" >> "$GITHUB_OUTPUT" + + if [ "$need_tag" = false ] && [ "$need_release" = false ]; then + echo "${TAG} is already published. Nothing to do." + else + echo "${TAG}: tag needed=${need_tag}, release needed=${need_release}" + fi + + - name: Extract release notes + if: steps.state.outputs.need_release == 'true' + env: + TAG: ${{ steps.version.outputs.tag }} run: | - awk '/^## /{ if (found) exit; found=1; next } found' CHANGELOG.md > RELEASE_NOTES.md + set -euo pipefail + + # cliff.toml renders headings as "## 0.1.0 (YYYY-MM-DD)", without the leading v. The + # top section must match VERSION; otherwise the release would carry the wrong notes. + heading="$(grep -m1 '^## ' CHANGELOG.md || true)" + case "$heading" in + "## ${TAG#v}" | "## ${TAG#v} "*) : ;; + *) + echo "::error::VERSION says ${TAG} but the top CHANGELOG.md section is '${heading}'." + echo "Refusing to publish mismatched release notes." + exit 1 + ;; + esac + + # Lines between this heading and the next, without the leading blank lines. + awk '/^## /{ if (found) exit; found=1; next } found' CHANGELOG.md \ + | awk 'NF { started = 1 } started' > RELEASE_NOTES.md + if [ ! -s RELEASE_NOTES.md ]; then + echo "::error::No release notes found under '${heading}'." + exit 1 + fi cat RELEASE_NOTES.md - name: Create tag + if: steps.state.outputs.need_tag == 'true' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG: ${{ steps.version.outputs.tag }} + RELEASE_SHA: ${{ steps.version.outputs.release_sha }} run: | set -euo pipefail - sha="$(git rev-parse HEAD)" gh api "repos/${GITHUB_REPOSITORY}/git/refs" \ -f "ref=refs/tags/${TAG}" \ - -f "sha=${sha}" + -f "sha=${RELEASE_SHA}" >/dev/null + echo "Tagged ${TAG} at ${RELEASE_SHA}." - name: Create GitHub Release + if: steps.state.outputs.need_release == 'true' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG: ${{ steps.version.outputs.tag }} run: | set -euo pipefail + # --verify-tag: fail instead of creating the tag if it does not exist. gh release create "$TAG" \ + --repo "$GITHUB_REPOSITORY" \ + --verify-tag \ --title "$TAG" \ --notes-file RELEASE_NOTES.md + echo "Published ${TAG}." diff --git a/CHANGELOG.md b/CHANGELOG.md index dd0b675b..c2643846 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,628 +1,626 @@ -# Changelog - -All notable changes to the Security Frameworks are documented here. - -## 0.0.1 (2026-09-01) - -### New content - -- adding section on encumbered wallets ([#258](https://github.com/security-alliance/frameworks/pull/258)) by @njelich -- Multisig for Protocols ([#239](https://github.com/security-alliance/frameworks/pull/239)) by @DicksonWu654 -- Treasury ops ([#247](https://github.com/security-alliance/frameworks/pull/247)) by @DicksonWu654 -- More context and instructions for DNSSEC and CAA sections ([#314](https://github.com/security-alliance/frameworks/pull/314)) by @gunnim -- [multisig] independent transaction verification requirement ([#335](https://github.com/security-alliance/frameworks/pull/335)) by @monperrus -- Enhancement: Adding SMTP DANE section to DNS security ([#329](https://github.com/security-alliance/frameworks/pull/329)) by @gunnim -- Chore - expand overview of each framework page ([#344](https://github.com/security-alliance/frameworks/pull/344)) by @scode2277 -- Integrating W3OSC's Multisig content into Frameworks ([#303](https://github.com/security-alliance/frameworks/pull/303)) by @DicksonWu654 -- Add back "Create Devops Cert & Updating 2 other Certs" ([#334](https://github.com/security-alliance/frameworks/pull/334)) by @DicksonWu654 -- Integrating w3os discord guide into frameworks ([#321](https://github.com/security-alliance/frameworks/pull/321)) by @DicksonWu654 -- Implementing W3OSC's account configuration guides into Frameworks ([#305](https://github.com/security-alliance/frameworks/pull/305)) by @DicksonWu654 -- AI Security Domain first commit ([#397](https://github.com/security-alliance/frameworks/pull/397)) by @mattaereal -- Content(add): Zoom hardening guide for opsec/endpoint ([#375](https://github.com/security-alliance/frameworks/pull/375)) by @artemisclaw82 -- Content(add): white hat frontrunning section in SEAL 911 war room guidelines ([#376](https://github.com/security-alliance/frameworks/pull/376)) by @artemisclaw82 -- Content(add): smart contract interaction security page under wallet-security ([#377](https://github.com/security-alliance/frameworks/pull/377)) by @artemisclaw82 -- DevSecOps: move sandboxing/isolation guidance out of AI Security (#398) -- verified ([#411](https://github.com/security-alliance/frameworks/pull/411)) by @frameworks-volunteer -- TLS-RPT ([#315](https://github.com/security-alliance/frameworks/pull/315)) by @gunnim -- content(devsecops): add Data Security & Contract Upgrade Checklist ([#385](https://github.com/security-alliance/frameworks/pull/385)) by @artemisclaw82 -- content(telegram): add passkeys to security guide ([#380](https://github.com/security-alliance/frameworks/pull/380)) by @artemisclaw82 -- Supply Chain Framework: expand the framework ([#410](https://github.com/security-alliance/frameworks/pull/410)) by @scode2277 -- content(opsec): add Secure Operating Systems guide ([#381](https://github.com/security-alliance/frameworks/pull/381)) by @artemisclaw82 -- content(governance): add Security Council Best Practices page ([#384](https://github.com/security-alliance/frameworks/pull/384)) by @artemisclaw82 -- Add multisig operational runbooks and documentation guidance ([#408](https://github.com/security-alliance/frameworks/pull/408)) by @DicksonWu654 -- Expand monitoring section ([#421](https://github.com/security-alliance/frameworks/pull/421)) by @JosepBove - -### Updated content - -- Restructuring opsec domain ([#299](https://github.com/security-alliance/frameworks/pull/299)) by @zedt3ster -- clarify template.mdx location in the contributing file ([#326](https://github.com/security-alliance/frameworks/pull/326)) by @gunnim -- fix: Certified protocols/partners fails to fetch ([#351](https://github.com/security-alliance/frameworks/pull/351)) by @DicksonWu654 - -### Enhancements - -- Add branch-aware robots.txt ([#330](https://github.com/security-alliance/frameworks/pull/330)) by @scode2277 -- adding custom 404 that doesn't redirect ([#327](https://github.com/security-alliance/frameworks/pull/327)) by @scode2277 -- Badge system for contributors ([#346](https://github.com/security-alliance/frameworks/pull/346)) by @scode2277 -- Fix/twitter preview image (it gets cropped when linking) ([#347](https://github.com/security-alliance/frameworks/pull/347)) by @scode2277 -- weekly spellchecker + linter outputs fix ([#322](https://github.com/security-alliance/frameworks/pull/322)) by @scode2277 -- Chore: style fixes for toc and sidebar + contributing files sync ([#353](https://github.com/security-alliance/frameworks/pull/353)) by @scode2277 -- Chore: Add workflow to remind contributors to update vocs.config.ts ([#358](https://github.com/security-alliance/frameworks/pull/358)) by @scode2277 -- feat: add printable checklists for SFC certifications ([#320](https://github.com/security-alliance/frameworks/pull/320)) by @madjin -- Chore: fix spellcheck + linter outputs, sync indexes, sync tags, sync badges ([#374](https://github.com/security-alliance/frameworks/pull/374)) by @scode2277 -- Chore: add canonical tags ([#383](https://github.com/security-alliance/frameworks/pull/383)) by @scode2277 -- feat(certs): Export All Certifications button on overview page ([#378](https://github.com/security-alliance/frameworks/pull/378)) by @artemisclaw82 -- Chore: Bump vocs to fix sidebar sections not opening on internal links ([#414](https://github.com/security-alliance/frameworks/pull/414)) by @scode2277 - -### Other - -Everything below predates our labelled-PR workflow: the original mdBook version of the site, the migration to vocs, the tagging and theming work, and the early framework drafts. Preserved in full since this is our first release. - -
-Full pre-workflow history (expand) - -- Initial commit privs by @mattaereal -- Working vanilla mdBook with catpuccino, and admonish by @mattaereal -- Hardcoding /book/ path as path_root to fix theme. Adding vercel config locally by @mattaereal -- Initial PoC structure. by @mattaereal -- Update structure by @mattaereal -- Creation of develop branch to run mdbook serve locally by @mattaereal -- Update gitignore by @mattaereal -- Hardcoding path again, after ignoring index.hbs. Should not be modified again unless necessary. by @mattaereal -- Update in structure by @mattaereal -- README.md contents, with installation and collaboration guidelines by @mattaereal -- Update issue templates by @mattaereal -- Workaround to develop on vercel as well as locally using serve.sh by @mattaereal -- Removing serve.sh workaround since develop deployment can be accessed via vercel sharing by @mattaereal -- Test to see vercel deployment develop sharing by @mattaereal -- Test to see vercel deployment develop sharing by @mattaereal -- trg intro test by @mattaereal -- SEAL intro update by @mattaereal -- What is it or isn't by @mattaereal -- README update and minor updates to intro section. by @mattaereal -- Major update with a lot of content. Some imgs are broken, need to be fixed. by @mattaereal -- Adding a way to load the logo over the ToC by @mattaereal -- Update SUMMARY.md by @0xFredrik -- Minor fixes by @0xFredrik -- Update awareness/README.md by @0xFredrik -- Update security-training.md by @0xFredrik -- Update social-engineering.md by @0xFredrik -- Update staying-up-to-date.md by @0xFredrik -- Update integrated-development-environments.md by @0xFredrik -- Create security-testing.md by @0xFredrik -- Update README.md by @0xFredrik -- Update cloud-data-encryption.md by @0xFredrik -- Create encryption-in-transit.md by @0xFredrik -- Update database-encryption.md by @0xFredrik -- Update email-encryption.md by @0xFredrik -- Update file-encryption.md by @0xFredrik -- Update full-disk-encryption.md by @0xFredrik -- Update hardware-encryption.md by @0xFredrik -- Update communication-encryption.md by @0xFredrik -- Update communication-encryption.md by @0xFredrik -- Update README.md by @0xFredrik -- Delete src/encryption/volume-encryption.md by @0xFredrik -- Update security-policies-procedures.md by @0xFredrik -- Update README.md by @0xFredrik -- Update mobile-application-security.md by @0xFredrik -- Create common-vulnerabilities.md by @0xFredrik -- Create security-tools-resources.md by @0xFredrik -- Update README.md by @0xFredrik -- Update compliance-regulatory-requirements.md by @0xFredrik -- Update risk-management.md by @0xFredrik -- Update security-metrics-kpis.md by @0xFredrik -- Update README.md by @0xFredrik -- Update role-based-access-control.md by @0xFredrik -- Update secure-authentication.md by @0xFredrik -- Create access-management-best-practises.md by @0xFredrik -- Update README.md by @0xFredrik -- Update communication-strategies.md by @0xFredrik -- Update incident-detection-and-response-mechanisms.md by @0xFredrik -- Update lessons-learned.md by @0xFredrik -- Update playbooks.md by @0xFredrik -- Update seal-911-war-room-guidelines.md by @0xFredrik -- Update zero-trust-principles.md by @0xFredrik -- Update hardware-wallets.md by @0xFredrik -- Update software-wallets.md by @0xFredrik -- Update README.md by @0xFredrik -- Update guidelines.md by @0xFredrik -- Update thresholds.md by @0xFredrik -- Update detecting-and-mitigating-insider-threats.md by @0xFredrik -- Update g-suite-security.md by @0xFredrik -- Update physical-security.md by @0xFredrik -- Update standard-operating-environment.md by @0xFredrik -- Update wireless-security.md by @0xFredrik -- Update README.md by @0xFredrik -- Update bug-bounties.md by @0xFredrik -- Update security-contact.md by @0xFredrik -- Update README.md by @0xFredrik -- Update data-removal-services.md by @0xFredrik -- Update digital-footprint.md by @0xFredrik -- Update financial-privacy-services.md by @0xFredrik -- Update privacy-focused-operating-systems-tools.md by @0xFredrik -- Update secure-browsing.md by @0xFredrik -- Update vpn-services.md by @0xFredrik -- Update README.md by @0xFredrik -- Update code-reviews-peer-audits.md by @0xFredrik -- Update secure-code-repositories-version-control.md by @0xFredrik -- Update secure-coding-standards-guidelines.md by @0xFredrik -- Update threat-modeling-secure-design-principles.md by @0xFredrik -- Update secure-code-repositories-version-control.md by @0xFredrik -- Update README.md by @0xFredrik -- Update compliance-checks.md by @0xFredrik -- Update infrastructure-as-code.md by @0xFredrik -- Update README.md by @0xFredrik -- Update dynamic-application-security-testing.md by @0xFredrik -- Update fuzz-testing.md by @0xFredrik -- Update security-regression-testing.md by @0xFredrik -- Update static-application-security-testing.md by @0xFredrik -- Update README.md by @0xFredrik -- Update dependency-awareness.md by @0xFredrik -- Update supply-chain-levels-software-artifacts.md by @0xFredrik -- Update README.md by @0xFredrik -- Update create-maintain-threat-models.md by @0xFredrik -- Update identity-mitigate-threats.md by @0xFredrik -- Update README.md by @0xFredrik -- Update phishing-social-engineering.md by @0xFredrik -- Update security-aware-culture.md by @0xFredrik -- Update security-training.md by @0xFredrik -- Adding a minimalistic crisis handbook by @mattaereal -- discord.md updates by @0xFredrik -- added self audit so it's aligned with the other community management docs by @0xFredrik -- google.md updates by @0xFredrik -- devsecops readme.md update by @0xFredrik -- Update code-signing.md by @0xFredrik -- Update continuous-integration-continuous-deployment.md by @0xFredrik -- Update repository-hardening.md by @0xFredrik -- Delete src/encryption/partition-encryption.md by @0xFredrik -- Update expectation.md by @0xFredrik -- Update preparation.md by @0xFredrik -- Update vendor-selection.md by @0xFredrik -- Update web-application-security.md by @0xFredrik -- Update how-to-navigate-the-website.md by @0xFredrik -- Update introduction.md by @0xFredrik -- Update overview-of-each-framework.md by @0xFredrik -- Update what-is-it.md by @0xFredrik -- Update what-it-isnt.md by @0xFredrik -- Delete src/infrastructure/identity-and-access-management.md by @0xFredrik -- Update README.md by @0xFredrik -- Update asset-inventory.md by @0xFredrik -- Update cloud.md by @0xFredrik -- Update ddos-protection.md by @0xFredrik -- Update dns-and-domain-registration.md by @0xFredrik -- Update network-security.md by @0xFredrik -- Update README.md by @0xFredrik -- Update cold-vs-hot-wallet.md by @0xFredrik -- Update custodial-vs-non-custodial.md by @0xFredrik -- Update signing-schemes.md by @0xFredrik -- Update README.md by @0xFredrik -- Update password-secrets-management.md by @0xFredrik -- Delete src/operational-security/telegram.md by @0xFredrik -- Delete src/privacy/encrypted-communication-tools.md by @0xFredrik -- Delete src/security-automation/threat-detection-response.md by @0xFredrik -- Update operating-system-security.md by @0xFredrik -- Update operating-system-security.md by @0xFredrik -- Update README.md by @0xFredrik -- Update README.md by @0xFredrik -- Update sim-swapping.md by @0xFredrik -- Update sim-swapping.md by @0xFredrik -- Update README.md by @0xFredrik -- Update README.md by @0xFredrik -- Update README.md by @0xFredrik -- Update README.md by @0xFredrik -- Update security-training.md by @0xFredrik -- Update social-engineering.md by @0xFredrik -- Update staying-up-to-date.md by @0xFredrik -- Update README.md by @0xFredrik -- Update discord.md by @0xFredrik -- Update google.md by @0xFredrik -- Update telegram.md by @0xFredrik -- Update twitter.md by @0xFredrik -- Update README.md by @0xFredrik -- Update code-signing.md by @0xFredrik -- Update continuous-integration-continuous-deployment.md by @0xFredrik -- Update integrated-development-environments.md by @0xFredrik -- Update repository-hardening.md by @0xFredrik -- Update security-testing.md by @0xFredrik -- Update repository-hardening.md by @0xFredrik -- Update introduction.md by @0xFredrik -- Update what-is-it.md by @0xFredrik -- Update README.md by @0xFredrik -- Update cloud-data-encryption.md by @0xFredrik -- Update database-encryption.md by @0xFredrik -- Update email-encryption.md by @0xFredrik -- Update encryption-in-transit.md by @0xFredrik -- Update full-disk-encryption.md by @0xFredrik -- Update hardware-encryption.md by @0xFredrik -- Update guidelines.md by @0xFredrik -- Update thresholds.md by @0xFredrik -- Update README.md by @0xFredrik -- Update compliance-checks.md by @0xFredrik -- Update infrastructure-as-code.md by @0xFredrik -- Update standard-operating-environment.md by @0xFredrik -- Update expectation.md by @0xFredrik -- Update preparation.md by @0xFredrik -- Update security-policies-procedures.md by @0xFredrik -- Update vendor-selection.md by @0xFredrik -- Update README.md by @0xFredrik -- Update common-vulnerabilities.md by @0xFredrik -- Update mobile-application-security.md by @0xFredrik -- Update security-tools-resources.md by @0xFredrik -- Update web-application-security.md by @0xFredrik -- Update README.md by @0xFredrik -- Update compliance-regulatory-requirements.md by @0xFredrik -- Update risk-management.md by @0xFredrik -- Update security-metrics-kpis.md by @0xFredrik -- Update README.md by @0xFredrik -- Update access-management-best-practises.md by @0xFredrik -- Update role-based-access-control.md by @0xFredrik -- Update secure-authentication.md by @0xFredrik -- Update README.md by @0xFredrik -- Update communication-strategies.md by @0xFredrik -- Update incident-detection-and-response-mechanisms.md by @0xFredrik -- Update lessons-learned.md by @0xFredrik -- Update playbooks.md by @0xFredrik -- Update README.md by @0xFredrik -- Update asset-inventory.md by @0xFredrik -- Update cloud.md by @0xFredrik -- Update ddos-protection.md by @0xFredrik -- Update dns-and-domain-registration.md by @0xFredrik -- Update network-security.md by @0xFredrik -- Update operating-system-security.md by @0xFredrik -- Update zero-trust-principles.md by @0xFredrik -- Update cold-vs-hot-wallet.md by @0xFredrik -- Update custodial-vs-non-custodial.md by @0xFredrik -- Update signing-schemes.md by @0xFredrik -- Update software-wallets.md by @0xFredrik -- Update README.md by @0xFredrik -- Update bug-bounties.md by @0xFredrik -- Update security-contact.md by @0xFredrik -- Update create-maintain-threat-models.md by @0xFredrik -- Update README.md by @0xFredrik -- Update phishing-social-engineering.md by @0xFredrik -- Update security-aware-culture.md by @0xFredrik -- Update security-training.md by @0xFredrik -- Update README.md by @0xFredrik -- Update dependency-awareness.md by @0xFredrik -- Update supply-chain-levels-software-artifacts.md by @0xFredrik -- Update README.md by @0xFredrik -- Update dynamic-application-security-testing.md by @0xFredrik -- Update security-regression-testing.md by @0xFredrik -- Update README.md by @0xFredrik -- Update code-reviews-peer-audits.md by @0xFredrik -- Update secure-code-repositories-version-control.md by @0xFredrik -- Update secure-coding-standards-guidelines.md by @0xFredrik -- Update threat-modeling-secure-design-principles.md by @0xFredrik -- Update README.md by @0xFredrik -- Update data-removal-services.md by @0xFredrik -- Update digital-footprint.md by @0xFredrik -- Update financial-privacy-services.md by @0xFredrik -- Update privacy-focused-operating-systems-tools.md by @0xFredrik -- Update secure-browsing.md by @0xFredrik -- Update vpn-services.md by @0xFredrik -- Update README.md by @0xFredrik -- Update detecting-and-mitigating-insider-threats.md by @0xFredrik -- Update g-suite-security.md by @0xFredrik -- Update password-secrets-management.md by @0xFredrik -- Update physical-security.md by @0xFredrik -- Update standard-operating-environment.md by @0xFredrik -- Update wireless-security.md by @0xFredrik -- Update mobile-application-security.md by @0xFredrik -- Update email-encryption.md by @0xFredrik -- Update web-application-security.md by @0xFredrik -- Update secure-code-repositories-version-control.md by @0xFredrik -- Update security-training.md by @0xFredrik -- Update social-engineering.md by @0xFredrik -- Update lessons-learned.md by @0xFredrik -- Update communication-strategies.md by @0xFredrik -- Update full-disk-encryption.md by @0xFredrik -- Update software-wallets.md by @0xFredrik -- Create CODE_OF_CONDUCT.md by @0xFredrik -- Update .gitignore by @0xFredrik -- Create md-lint.yaml by @0xFredrik -- Create spell-check.yml by @0xFredrik -- Create PULL_REQUEST_TEMPLATE.md by @0xFredrik -- Create wordlist.txt by @0xFredrik -- Create content-request.md by @0xFredrik -- Create contributing.md by @0xFredrik -- Update SUMMARY.md by @0xFredrik -- Update contributing.md by @0xFredrik -- Update contributing.md by @0xFredrik -- Update README.md by @0xFredrik -- Update README.md by @0xFredrik -- Update security-training.md by @0xFredrik -- Update social-engineering.md by @0xFredrik -- Update staying-up-to-date.md by @0xFredrik -- Update SUMMARY.md by @0xFredrik -- Update SUMMARY.md by @0xFredrik -- Delete src/misc/contributors.md by @0xFredrik -- Moving contributors.md into contribute folder by @0xFredrik -- Update introduction.md by @0xFredrik -- Update README.md by @0xFredrik -- Update security-training.md by @0xFredrik -- Update social-engineering.md by @0xFredrik -- Update staying-up-to-date.md by @0xFredrik -- Update contributing.md by @0xFredrik -- Update introduction.md by @0xFredrik -- Update contributing.md by @0xFredrik -- Stage 2 of merge by @mattaereal -- Update content-request.md by @mattaereal -- Create update-request.md by @mattaereal -- Update content-request.md by @mattaereal -- Update update-request.md by @mattaereal -- Added suggested feedback for compliance, IAM, how to navigate the website, and more. by @mattaereal -- Update seal-911-war-room-guidelines.md by @mattaereal -- Added the correct path to the contribution page. by @mattaereal -- Feedback applied to passwords, SE, and security training. by @mattaereal -- Update README.md with recent changes to collaboration and local setup instructions by @mattaereal -- Updated build setup to newest version by @mattaereal -- Improved best practices on email encryption by @mattaereal -- Improved best practices on cloud encryption by @mattaereal -- Modified serve.sh script to be compatible with macos by @tebayoso -- Tags working by @tebayoso -- Added serve and build specs by @tebayoso -- Cleaned up eol by @tebayoso -- Added EOL to editorconfig by @tebayoso -- Upgraded vercel build by @tebayoso -- Added sample tags to each page, improved serve.sh script, and updated various documentation files to enhance clarity and completeness by @mattaereal -- Modified gitignore to accept handlebars index. by @mattaereal -- Changed URLS and minor typo on serve script. by @mattaereal -- Trying a new way to deploy to get rid of a hardcoding workaround on index.hbs by @mattaereal -- Trying a new vercel.json config by @mattaereal -- Deprecating previous replacement with sed on serve.sh by @mattaereal -- Removing old /book path from url on README.md by @mattaereal -- Updating readme to match current local setup by @mattaereal -- Added improved tag images by @tebayoso -- Tags Colors working by @tebayoso -- Fix wordlist.txt by @0xFredrik -- Added collaborate stripe by @tebayoso -- Updating current tags to incorporate HR, and a few more by @mattaereal -- Improvemets in tag selection and announcement banner by @tebayoso -- Clear tags and filters by @tebayoso -- Update theme/index.hbs by @tebayoso -- fix typos by @zedt3ster -- expand wordlist and order alphabetically by @zedt3ster -- more word exclusions by @zedt3ster -- more typo fixes by @zedt3ster -- more typo fixes by @zedt3ster -- Updating wordlist.txt and some markdown linting fixes by @mattaereal -- Jump of line fix in README by @mattaereal -- Updating wordlist by @mattaereal -- docs: Update README ##pull-requests by @Robert-MacWha -- fix: Fix typo by @Robert-MacWha -- fix: typos in pr_template by @Robert-MacWha -- add SEAL logo as favicon by @zedt3ster -- feat: improved tag generation by @Robert-MacWha -- feat: Update tag display system by @Robert-MacWha -- feat: remove duplicate code & document methods by @Robert-MacWha -- refactor: move JS and CSS to seperate files by @Robert-MacWha -- style: Added margin around page-tags by @Robert-MacWha -- refactor: Extract tag initialization logic into seperate methods by @Robert-MacWha -- fix: announcement-stripe overflowing at lower horizontal resolutions by @Robert-MacWha -- feat: implemented AND selection for tags. by @Robert-MacWha -- feat: remove HTML styling on tag-search by @Robert-MacWha -- Adding a few more words to wordlist.txt by @mattaereal -- feat: Bookmarks ([#83](https://github.com/security-alliance/frameworks/pull/83)) by @Robert-MacWha -- Safe Harbor Docs ([#92](https://github.com/security-alliance/frameworks/pull/92)) by @Robert-MacWha -- Add yaml frontmatter & build time tags ([#102](https://github.com/security-alliance/frameworks/pull/102)) by @Robert-MacWha -- Adding .code-workspace to gitignore by @mattaereal -- Merge from develop ([#85](https://github.com/security-alliance/frameworks/pull/85)) by @mattaereal -- Changing default theme to navy by @mattaereal -- First commit for this framework. Introduction refactored. by @mattaereal -- Discord update, with ToC by @mattaereal -- X (Twitter) update, with ToC by @mattaereal -- Normalizing summary.md by @mattaereal -- Updating Telegram, also a ToC and MITM attack by @mattaereal -- Updating Google, added ToC, and SUMMARY by @mattaereal -- Normalizing dividers by @mattaereal -- Minor modifications, reordering SUMMARY by @mattaereal -- Update src/community-management/README.md by @mattaereal -- Update src/community-management/README.md by @mattaereal -- Added key takeaways and improved some wording. by @mattaereal -- Trying JoreAli's mdBook pagetoc by @mattaereal -- feat: fix toc and package theme into "toc" folder ([#100](https://github.com/security-alliance/frameworks/pull/100)) by @Robert-MacWha -- Update spell-check.yml by @mattaereal -- Update discord.md by @NFTDreww -- Update google.md by @NFTDreww -- Update telegram.md by @NFTDreww -- Update twitter.md by @NFTDreww -- Improved formatting and summarized contents by @mattaereal -- Improved formatting and summarized contents (google) by @mattaereal -- Improved formatting and summarized contents (telegram) by @mattaereal -- Improved formatting and summarized contents (X) by @mattaereal -- Fw community mgmt ([#99](https://github.com/security-alliance/frameworks/pull/99)) by @NFTDreww -- Solving conflicts from previous merge by @mattaereal -- Solving more conflicts from previous merge. My ide messed up something by @mattaereal -- Adding following banner, improved ToC, footer, and more by @mattaereal -- Normalizing platform contents for comm mgmt by @mattaereal -- update telegram session management instructions ([#104](https://github.com/security-alliance/frameworks/pull/104)) by @matt-dragonfly -- Removing remove from toc title for twitter by @mattaereal -- Tweaked footer by @mattaereal -- Adding conditional banner, and prebuild to change SUMMARY depending on branch. by @mattaereal -- Testing pre-build run on develop by @mattaereal -- Merge from develop, testing conditional banner by @mattaereal -- Merge from develop! New stage. ([#111](https://github.com/security-alliance/frameworks/pull/111)) by @mattaereal -- Updating summary by @mattaereal -- Merge prebuild-summary into develop ([#114](https://github.com/security-alliance/frameworks/pull/114)) by @mattaereal -- Merge prebuild-summary into develop ([#116](https://github.com/security-alliance/frameworks/pull/116)) by @mattaereal -- Updating prebuild.sh to work with vercel's config and fixing grammar ([#117](https://github.com/security-alliance/frameworks/pull/117)) by @mattaereal -- Merge prebuild-summary into develop ([#118](https://github.com/security-alliance/frameworks/pull/118)) by @mattaereal -- Contributors first run by @mattaereal -- Tags and Contributors plugin merge into mdbook-metadata, plus an example by @mattaereal -- Cleaned contributors plugin, removing unused code by @mattaereal -- Fix broken link by @engn33r -- Updating spellcheck wordlist.txt by @mattaereal -- Updating spellcheck wordlist.txt (removing invalid character by @mattaereal -- Updating spellcheck wordlist.txt (adding draww again). This spellcheck I swear to god... by @mattaereal -- Initial commit for this updated framework by @mattaereal -- Adding new words to wordlist by @mattaereal -- Merging user-team-security into awareness, at least for now. A lot of overlap by @mattaereal -- Updating summary to remove user-team-security by @mattaereal -- Proof reading and improving current contents with Claude. Adding Key takeaways. by @mattaereal -- Removing user-team-security folder, no longer needed after merging it with awareness. by @mattaereal -- Added prebuild.sh to vercel_build and updated Summaries. by @mattaereal -- Updating prebuild to work in vercel for dynamic summaries. by @mattaereal -- Updating wordlist as well for summaries by @mattaereal -- Updating wordlist by @mattaereal -- Updating prebuild config. by @mattaereal -- Restructuring contributors and tags generation by @mattaereal -- Improving the format of contributors on the contributing final list by @mattaereal -- Forgot to keep track of these files on the previous commit. by @mattaereal -- Moved CSS from within rust to actual CSS/HTML files, with a fallback in rust for some themes, but mainly files. by @mattaereal -- Fix announcement banner width ([#131](https://github.com/security-alliance/frameworks/pull/131)) by @davidthegardens -- feat: remove banner from production site ([#133](https://github.com/security-alliance/frameworks/pull/133)) by @Robert-MacWha -- chore: update Cargo.lock for mdbook-metadata plugin by @mattaereal -- Updating contributions by @mattaereal -- Contributors style and formatting upgrade ([#136](https://github.com/security-alliance/frameworks/pull/136)) by @mattaereal -- Minor theme fix, bullets on outline by @mattaereal -- Updated contributor list with correct information by @mattaereal -- Merging develop from mdbook-contributors ([#138](https://github.com/security-alliance/frameworks/pull/138)) by @mattaereal -- Ens best practices ([#139](https://github.com/security-alliance/frameworks/pull/139)) by @Ghadi8 -- ENS, Awareness, Summaries and Contributors hygiene. by @mattaereal -- Removing track of contributorsindex and tagsindex by @mattaereal -- Code review additions ([#145](https://github.com/security-alliance/frameworks/pull/145)) by @ElliotFriedman -- Updated contributing and readme.md by @mattaereal -- Removed catpuccin, updated mdbook and admonish. ([#147](https://github.com/security-alliance/frameworks/pull/147)) by @mattaereal -- Clean update of logo and favicon. ([#151](https://github.com/security-alliance/frameworks/pull/151)) by @mattaereal -- Updating develop to the new and more humane beginning of a written Opsec Framework ([#154](https://github.com/security-alliance/frameworks/pull/154)) by @mattaereal -- Updating Opsec with latest updates ([#157](https://github.com/security-alliance/frameworks/pull/157)) by @mattaereal -- Initial draft of personal security travel guide! ([#158](https://github.com/security-alliance/frameworks/pull/158)) by @mattaereal -- Attribution by @mattaereal -- Updating naming on opsec travel guide by @mattaereal -- Updating, and re-ordering paragraphs from opsec travel guide by @mattaereal -- Attribution to sources by @mattaereal -- Add Secure Multisig Signing Process ([#122](https://github.com/security-alliance/frameworks/pull/122)) by @engn33r -- Removing the old operational-security folder, moving secure-multisig contents within wallet-security, and re-generated the overview of frameworks with AI. by @mattaereal -- feat: Safe Harbor Framework ([#144](https://github.com/security-alliance/frameworks/pull/144)) by @Robert-MacWha -- doc: Instruction for re-writing history to sign commits ([#156](https://github.com/security-alliance/frameworks/pull/156)) by @Robert-MacWha -- Tidy plugins ([#143](https://github.com/security-alliance/frameworks/pull/143)) by @Robert-MacWha -- feat: overhaul of the Wallet Security section ([#164](https://github.com/security-alliance/frameworks/pull/164)) by @pinalikefruit -- feat: fix extra fields & add verbose errors ([#167](https://github.com/security-alliance/frameworks/pull/167)) by @Robert-MacWha -- Fix several misc ([#168](https://github.com/security-alliance/frameworks/pull/168)) by @mattaereal -- Removing spell-check from develop. Only on main from now on. Exploratory. by @mattaereal -- feat: security testing - solidity focused ([#163](https://github.com/security-alliance/frameworks/pull/163)) by @PatrickAlphaC -- Introducing Decentralized IR Framework ([#165](https://github.com/security-alliance/frameworks/pull/165)) by @relotnek -- feat: external security reviews & patrick addition ([#160](https://github.com/security-alliance/frameworks/pull/160)) by @PatrickAlphaC -- Adding to the outline the latest pushed content. by @mattaereal -- Bump mdbook version ([#177](https://github.com/security-alliance/frameworks/pull/177)) by @davidthegardens -- feat: added more information on wallet security ([#173](https://github.com/security-alliance/frameworks/pull/173)) by @PatrickAlphaC -- Update PULL_REQUEST_TEMPLATE.md ([#174](https://github.com/security-alliance/frameworks/pull/174)) by @mattaereal -- fix: stewards ([#172](https://github.com/security-alliance/frameworks/pull/172)) by @PatrickAlphaC -- Update tldr.md ([#181](https://github.com/security-alliance/frameworks/pull/181)) by @NFTDreww -- Update README.md ([#178](https://github.com/security-alliance/frameworks/pull/178)) by @GodwinDA -- Update implementation-process.md ([#179](https://github.com/security-alliance/frameworks/pull/179)) by @GodwinDA -- feat: updating linting, devcontainer, and local development ([#184](https://github.com/security-alliance/frameworks/pull/184)) by @PatrickAlphaC -- Going back to 0.4.40 stable. by @mattaereal -- Fix spelling issues and update wordlist ([#188](https://github.com/security-alliance/frameworks/pull/188)) by @mattaereal -- Fix typos in mdbook-metadata README.md and add renderer to wordlist by @mattaereal -- Update threat-modeling-overview.md ([#182](https://github.com/security-alliance/frameworks/pull/182)) by @damboy0 -- Updating Safe Harbor Documentation ([#186](https://github.com/security-alliance/frameworks/pull/186)) by @DicksonWu654 -- Updating outlines. Removing empty frameworks from main by @mattaereal -- Fixing broken link in PR template by @mattaereal -- Fixing grammar issues and spellcheck by @mattaereal -- 3 frameworks, contributors and spellcheck (Wallet Security, External Security Reviews, and Security Testing frameworks) ([#187](https://github.com/security-alliance/frameworks/pull/187)) by @mattaereal -- feat: handle reverse records per chain ([#199](https://github.com/security-alliance/frameworks/pull/199)) by @Ghadi8 -- Update Safe Harbor documentation for clarity and consistency ([#195](https://github.com/security-alliance/frameworks/pull/195)) by @DicksonWu654 -- Fix cross-site image loading issues ([#200](https://github.com/security-alliance/frameworks/pull/200)) by @Robert-MacWha -- quick fix for external security reviews by @mattaereal -- Fixed DevContainer Issue + github cli + Updated Documentation + Pre-build docker image ([#198](https://github.com/security-alliance/frameworks/pull/198)) by @DicksonWu654 -- Update link in Identity and Access Management documentation for accuracy ([#203](https://github.com/security-alliance/frameworks/pull/203)) by @DicksonWu654 -- Update links in self-checklist.md for improved navigation ([#205](https://github.com/security-alliance/frameworks/pull/205)) by @DicksonWu654 -- feat: Add insider-threats framework (DPRK IT Workers) ([#193](https://github.com/security-alliance/frameworks/pull/193)) by @shortdoom -- Addition of a Mutation Testing Section ([#180](https://github.com/security-alliance/frameworks/pull/180)) by @nbelenkov -- docs: update wallet security resources ([#213](https://github.com/security-alliance/frameworks/pull/213)) by @pinalikefruit -- Add manual review page in External Security Reviews framework. ([#183](https://github.com/security-alliance/frameworks/pull/183)) by @the-caliber -- Update guide to put some realistic info a bout juice jacking by @mattaereal -- Updated dev ([#215](https://github.com/security-alliance/frameworks/pull/215)) by @Robert-MacWha -- Updating main on missing commits due to previous selective-merging ([#192](https://github.com/security-alliance/frameworks/pull/192)) by @mattaereal -- quick fix for external security reviews by @mattaereal -- Adding dobs suggestions by @mattaereal -- Add Yaniv Sofer as a contributor and update review roles in insider t… ([#221](https://github.com/security-alliance/frameworks/pull/221)) by @DicksonWu654 -- hotfix: fix broken summary.md.main link by @Robert-MacWha -- fix: naming change - explicit DPRK IT Workers framework ([#223](https://github.com/security-alliance/frameworks/pull/223)) by @shortdoom -- Incident management playbook ([#224](https://github.com/security-alliance/frameworks/pull/224)) by @00xWizard -- Incident management playbooks ([#233](https://github.com/security-alliance/frameworks/pull/233)) by @scode2277 -- Vocs Migration ([#227](https://github.com/security-alliance/frameworks/pull/227)) by @scode2277 -- Restructure README.md and CONTRIBUTING.md ([#225](https://github.com/security-alliance/frameworks/pull/225)) by @scode2277 -- Fix logo path in README.md ([#237](https://github.com/security-alliance/frameworks/pull/237)) by @scode2277 -- Update telegram.mdx ([#243](https://github.com/security-alliance/frameworks/pull/243)) by @aviggiano -- feat: update the PULL_REQUEST_TEMPLATE for vocs ([#245](https://github.com/security-alliance/frameworks/pull/245)) by @scode2277 -- feat: Benchmark component ([#241](https://github.com/security-alliance/frameworks/pull/241)) by @Robert-MacWha -- feat: create mermaid wrapper pre-build script ([#242](https://github.com/security-alliance/frameworks/pull/242)) by @scode2277 -- chore(images): migrate all images to S3 ([#252](https://github.com/security-alliance/frameworks/pull/252)) by @scode2277 -- fix: CONTRIBUTING.md + contributing.mdx ([#250](https://github.com/security-alliance/frameworks/pull/250)) by @scode2277 -- chore: update tags ([#253](https://github.com/security-alliance/frameworks/pull/253)) by @scode2277 -- fix(flickering on reload): remove redirects from vercel.json ([#249](https://github.com/security-alliance/frameworks/pull/249)) by @scode2277 -- chore(spellcheck): migrate from Aspell to CSpell ([#251](https://github.com/security-alliance/frameworks/pull/251)) by @scode2277 -- chore: add temporary patch for Vocs search indexing issue ([#257](https://github.com/security-alliance/frameworks/pull/257)) by @scode2277 -- fix: branch-related files ([#259](https://github.com/security-alliance/frameworks/pull/259)) by @scode2277 -- Adding indexes! index.mdx -> index.html ([#260](https://github.com/security-alliance/frameworks/pull/260)) by @mattaereal -- Migrating from npm to pnpm ([#261](https://github.com/security-alliance/frameworks/pull/261)) by @mattaereal -- fix: remove duplicate framework from sidebar ([#262](https://github.com/security-alliance/frameworks/pull/262)) by @scode2277 -- Fix/markdown lint outputs ([#271](https://github.com/security-alliance/frameworks/pull/271)) by @scode2277 -- chore: add pre-build script to sync the contributing files ([#264](https://github.com/security-alliance/frameworks/pull/264)) by @scode2277 -- chore: update the issue templates to be more frameworks-customized ([#265](https://github.com/security-alliance/frameworks/pull/265)) by @scode2277 -- chore: add og images for preview links ([#276](https://github.com/security-alliance/frameworks/pull/276)) by @scode2277 -- feat/issue-forms ([#279](https://github.com/security-alliance/frameworks/pull/279)) by @scode2277 -- DNS & Domain security PR (final) ([#284](https://github.com/security-alliance/frameworks/pull/284)) by @mattaereal -- Fix/dickson slug in infra framework ([#285](https://github.com/security-alliance/frameworks/pull/285)) by @scode2277 -- chore: upgrade filter ([#277](https://github.com/security-alliance/frameworks/pull/277)) by @scode2277 -- update collapsed sections ([#286](https://github.com/security-alliance/frameworks/pull/286)) by @scode2277 -- Monthly update & migration (mdbook -> vocs) ([#255](https://github.com/security-alliance/frameworks/pull/255)) by @mattaereal -- Updating vsconfig to enable new updates on main by @mattaereal -- Updating vsconfig to enable new updates on main ([#289](https://github.com/security-alliance/frameworks/pull/289)) by @mattaereal -- Chore/travel guide update ([#291](https://github.com/security-alliance/frameworks/pull/291)) by @scode2277 -- SEAL Certifications incorporation, including 5 certs ([#294](https://github.com/security-alliance/frameworks/pull/294)) by @Robert-MacWha -- Certs fix: adding current status to overview and minor typos/grammar improvements ([#296](https://github.com/security-alliance/frameworks/pull/296)) by @DicksonWu654 -- Certs fix: Updating certified partners ([#297](https://github.com/security-alliance/frameworks/pull/297)) by @DicksonWu654 -- Sync Main ([#295](https://github.com/security-alliance/frameworks/pull/295)) by @Robert-MacWha -- Wallet security multisig content ([#275](https://github.com/security-alliance/frameworks/pull/275)) by @DicksonWu654 -- fix: update safe mobile app references and titles ([#292](https://github.com/security-alliance/frameworks/pull/292)) by @compojoom -- Create Devops Cert & Updating 2 other Certs ([#304](https://github.com/security-alliance/frameworks/pull/304)) by @DicksonWu654 -- Pnpm update ([#308](https://github.com/security-alliance/frameworks/pull/308)) by @Robert-MacWha -- fixing spotlight zone ([#311](https://github.com/security-alliance/frameworks/pull/311)) by @scode2277 -- making the vite deadlinks error just a warning ([#312](https://github.com/security-alliance/frameworks/pull/312)) by @scode2277 -- Revert "Create Devops Cert & Updating 2 other Certs" ([#317](https://github.com/security-alliance/frameworks/pull/317)) by @DicksonWu654 -- Restore automated tag colors and fix broken link ([#310](https://github.com/security-alliance/frameworks/pull/310)) by @scode2277 -- Add Isaac and Dickson as stewards ([#316](https://github.com/security-alliance/frameworks/pull/316)) by @DicksonWu654 -- fix md-linter path in the github workflow ([#331](https://github.com/security-alliance/frameworks/pull/331)) by @scode2277 -- Add meta descriptions to every page for SEO enhancement ([#324](https://github.com/security-alliance/frameworks/pull/324)) by @scode2277 -- Remove misadded files ([#338](https://github.com/security-alliance/frameworks/pull/338)) by @scode2277 -- Bump up react-router-dom dep ([#341](https://github.com/security-alliance/frameworks/pull/341)) by @scode2277 -- Making the searchbar indexer not run in local builds ([#348](https://github.com/security-alliance/frameworks/pull/348)) by @scode2277 -- Certs: Changes to Multisig Cert from Auditor's Feedback ([#339](https://github.com/security-alliance/frameworks/pull/339)) by @DicksonWu654 -- Certs: SFC DNS fixes based on feedback ([#340](https://github.com/security-alliance/frameworks/pull/340)) by @DicksonWu654 -- fix: restore Tailwind usage for Certs components after vocs upgrade ([#354](https://github.com/security-alliance/frameworks/pull/354)) by @scode2277 -- Chore: fix index generator titles/ordering + update fetched tags ([#352](https://github.com/security-alliance/frameworks/pull/352)) by @scode2277 -- Update Safe Harbor documentation for clarity and accuracy ([#356](https://github.com/security-alliance/frameworks/pull/356)) by @DicksonWu654 -- Fix double title suffix by adding titleTemplate config ([#361](https://github.com/security-alliance/frameworks/pull/361)) by @smagdali -- Cert Multisig Updates ([#362](https://github.com/security-alliance/frameworks/pull/362)) by @DicksonWu654 -- Certs Incident Response update ([#363](https://github.com/security-alliance/frameworks/pull/363)) by @DicksonWu654 -- Certs DNS Update ([#364](https://github.com/security-alliance/frameworks/pull/364)) by @DicksonWu654 -- Certs treasury ops update ([#365](https://github.com/security-alliance/frameworks/pull/365)) by @DicksonWu654 -- Certs workspace update ([#366](https://github.com/security-alliance/frameworks/pull/366)) by @DicksonWu654 -- Certs devops update ([#367](https://github.com/security-alliance/frameworks/pull/367)) by @DicksonWu654 -- Update vocs.config.ts to explore frameworks and outline collapsed or not ([#368](https://github.com/security-alliance/frameworks/pull/368)) by @mattaereal -- Merge Develop into Main ([#298](https://github.com/security-alliance/frameworks/pull/298)) by @davidthegardens -- Grammar fix on-chain-adoption-guide.mdx by @mattaereal -- Update wordlist.txt by @mattaereal -- Add reauthentication to wordlist.txt by @mattaereal -- Rename files with '&' to 'and' for URL compatibility ([#372](https://github.com/security-alliance/frameworks/pull/372)) by @smagdali -- Chore: add sitemap.xml ([#371](https://github.com/security-alliance/frameworks/pull/371)) by @scode2277 -- Update styles.css by @mattaereal -- Enhancement: Extending sidebar reminder to work on PRs from forks too by using pull_request_target ([#373](https://github.com/security-alliance/frameworks/pull/373)) by @scode2277 -- Fix: vocs.config path in index generator + added more in depth escapes for ts syntax ([#394](https://github.com/security-alliance/frameworks/pull/394)) by @scode2277 -- chore: migrate preview deployments from Vercel to Cloudflare Pages via GitHub Actions ([#395](https://github.com/security-alliance/frameworks/pull/395)) by @scode2277 -- Chore: Remove production workflow as it works with the git integration ([#402](https://github.com/security-alliance/frameworks/pull/402)) by @scode2277 -- Chore: weekly repo cleanup ([#413](https://github.com/security-alliance/frameworks/pull/413)) by @scode2277 -- Incident response template integration ([#407](https://github.com/security-alliance/frameworks/pull/407)) by @DicksonWu654 -- Revert "chore(deps): bump the npm_and_yarn group across 1 directory with 2 updates" ([#426](https://github.com/security-alliance/frameworks/pull/426)) by @mattaereal -- Fix indentation for fact-check contributor entry ([#427](https://github.com/security-alliance/frameworks/pull/427)) by @mattaereal -- Fix typos across docs ([#415](https://github.com/security-alliance/frameworks/pull/415)) by @DicksonWu654 -- Incident management attribution cleanup ([#423](https://github.com/security-alliance/frameworks/pull/423)) by @DicksonWu654 -- Clarify preview feedback path on contribution docs ([#418](https://github.com/security-alliance/frameworks/pull/418)) by @DicksonWu654 -- Updating main from develop ([#436](https://github.com/security-alliance/frameworks/pull/436)) by @scode2277 -- Chore: making Monitoring, DevSecOps, Supply Chain, AI Security and In… ([#438](https://github.com/security-alliance/frameworks/pull/438)) by @scode2277 -- Monthly Main branch update ([#486](https://github.com/security-alliance/frameworks/pull/486)) by @scode2277 -- Chore: monthly .org update ([#552](https://github.com/security-alliance/frameworks/pull/552)) by @scode2277 -- Chore: monthly .org update (#617) - -
+# Changelog + +All notable changes to the Security Frameworks are documented here. + +## 0.0.1 (2026-09-01) + +### New content + +- adding section on encumbered wallets ([#258](https://github.com/security-alliance/frameworks/pull/258)) by @njelich +- Multisig for Protocols ([#239](https://github.com/security-alliance/frameworks/pull/239)) by @DicksonWu654 +- DNS & Domain security PR (final) ([#284](https://github.com/security-alliance/frameworks/pull/284)) by @mattaereal +- Treasury ops ([#247](https://github.com/security-alliance/frameworks/pull/247)) by @DicksonWu654 +- Wallet security multisig content ([#275](https://github.com/security-alliance/frameworks/pull/275)) by @DicksonWu654 +- More context and instructions for DNSSEC and CAA sections ([#314](https://github.com/security-alliance/frameworks/pull/314)) by @gunnim +- [multisig] independent transaction verification requirement ([#335](https://github.com/security-alliance/frameworks/pull/335)) by @monperrus +- Enhancement: Adding SMTP DANE section to DNS security ([#329](https://github.com/security-alliance/frameworks/pull/329)) by @gunnim +- Chore - expand overview of each framework page ([#344](https://github.com/security-alliance/frameworks/pull/344)) by @scode2277 +- Integrating W3OSC's Multisig content into Frameworks ([#303](https://github.com/security-alliance/frameworks/pull/303)) by @DicksonWu654 +- Add back "Create Devops Cert & Updating 2 other Certs" ([#334](https://github.com/security-alliance/frameworks/pull/334)) by @DicksonWu654 +- Integrating w3os discord guide into frameworks ([#321](https://github.com/security-alliance/frameworks/pull/321)) by @DicksonWu654 +- Implementing W3OSC's account configuration guides into Frameworks ([#305](https://github.com/security-alliance/frameworks/pull/305)) by @DicksonWu654 +- AI Security Domain first commit ([#397](https://github.com/security-alliance/frameworks/pull/397)) by @mattaereal +- Content(add): Zoom hardening guide for opsec/endpoint ([#375](https://github.com/security-alliance/frameworks/pull/375)) by @artemisclaw82 +- Content(add): white hat frontrunning section in SEAL 911 war room guidelines ([#376](https://github.com/security-alliance/frameworks/pull/376)) by @artemisclaw82 +- Content(add): smart contract interaction security page under wallet-security ([#377](https://github.com/security-alliance/frameworks/pull/377)) by @artemisclaw82 +- DevSecOps: move sandboxing/isolation guidance out of AI Security (#398) -- verified ([#411](https://github.com/security-alliance/frameworks/pull/411)) by @frameworks-volunteer +- Incident response template integration ([#407](https://github.com/security-alliance/frameworks/pull/407)) by @DicksonWu654 +- TLS-RPT ([#315](https://github.com/security-alliance/frameworks/pull/315)) by @gunnim +- content(devsecops): add Data Security & Contract Upgrade Checklist ([#385](https://github.com/security-alliance/frameworks/pull/385)) by @artemisclaw82 +- content(telegram): add passkeys to security guide ([#380](https://github.com/security-alliance/frameworks/pull/380)) by @artemisclaw82 +- Supply Chain Framework: expand the framework ([#410](https://github.com/security-alliance/frameworks/pull/410)) by @scode2277 +- content(opsec): add Secure Operating Systems guide ([#381](https://github.com/security-alliance/frameworks/pull/381)) by @artemisclaw82 +- content(governance): add Security Council Best Practices page ([#384](https://github.com/security-alliance/frameworks/pull/384)) by @artemisclaw82 +- Add multisig operational runbooks and documentation guidance ([#408](https://github.com/security-alliance/frameworks/pull/408)) by @DicksonWu654 +- Expand monitoring section ([#421](https://github.com/security-alliance/frameworks/pull/421)) by @JosepBove + +### Updated content + +- Restructure README.md and CONTRIBUTING.md ([#225](https://github.com/security-alliance/frameworks/pull/225)) by @scode2277 +- Update telegram.mdx ([#243](https://github.com/security-alliance/frameworks/pull/243)) by @aviggiano +- Chore/travel guide update ([#291](https://github.com/security-alliance/frameworks/pull/291)) by @scode2277 +- fix: update safe mobile app references and titles ([#292](https://github.com/security-alliance/frameworks/pull/292)) by @compojoom +- Restructuring opsec domain ([#299](https://github.com/security-alliance/frameworks/pull/299)) by @zedt3ster +- Add Isaac and Dickson as stewards ([#316](https://github.com/security-alliance/frameworks/pull/316)) by @DicksonWu654 +- clarify template.mdx location in the contributing file ([#326](https://github.com/security-alliance/frameworks/pull/326)) by @gunnim +- fix: Certified protocols/partners fails to fetch ([#351](https://github.com/security-alliance/frameworks/pull/351)) by @DicksonWu654 +- Update Safe Harbor documentation for clarity and accuracy ([#356](https://github.com/security-alliance/frameworks/pull/356)) by @DicksonWu654 +- Incident management attribution cleanup ([#423](https://github.com/security-alliance/frameworks/pull/423)) by @DicksonWu654 +- Clarify preview feedback path on contribution docs ([#418](https://github.com/security-alliance/frameworks/pull/418)) by @DicksonWu654 +- Chore: making Monitoring, DevSecOps, Supply Chain, AI Security and In… ([#438](https://github.com/security-alliance/frameworks/pull/438)) by @scode2277 + +### Enhancements + +- feat: update the PULL_REQUEST_TEMPLATE for vocs ([#245](https://github.com/security-alliance/frameworks/pull/245)) by @scode2277 +- feat: Benchmark component ([#241](https://github.com/security-alliance/frameworks/pull/241)) by @Robert-MacWha +- feat: create mermaid wrapper pre-build script ([#242](https://github.com/security-alliance/frameworks/pull/242)) by @scode2277 +- chore(images): migrate all images to S3 ([#252](https://github.com/security-alliance/frameworks/pull/252)) by @scode2277 +- chore: update tags ([#253](https://github.com/security-alliance/frameworks/pull/253)) by @scode2277 +- chore(spellcheck): migrate from Aspell to CSpell ([#251](https://github.com/security-alliance/frameworks/pull/251)) by @scode2277 +- Adding indexes! index.mdx -> index.html ([#260](https://github.com/security-alliance/frameworks/pull/260)) by @mattaereal +- Migrating from npm to pnpm ([#261](https://github.com/security-alliance/frameworks/pull/261)) by @mattaereal +- chore: add pre-build script to sync the contributing files ([#264](https://github.com/security-alliance/frameworks/pull/264)) by @scode2277 +- chore: update the issue templates to be more frameworks-customized ([#265](https://github.com/security-alliance/frameworks/pull/265)) by @scode2277 +- chore: add og images for preview links ([#276](https://github.com/security-alliance/frameworks/pull/276)) by @scode2277 +- feat/issue-forms ([#279](https://github.com/security-alliance/frameworks/pull/279)) by @scode2277 +- chore: upgrade filter ([#277](https://github.com/security-alliance/frameworks/pull/277)) by @scode2277 +- update collapsed sections ([#286](https://github.com/security-alliance/frameworks/pull/286)) by @scode2277 +- Updating vsconfig to enable new updates on main ([#289](https://github.com/security-alliance/frameworks/pull/289)) by @mattaereal +- Pnpm update ([#308](https://github.com/security-alliance/frameworks/pull/308)) by @Robert-MacWha +- making the vite deadlinks error just a warning ([#312](https://github.com/security-alliance/frameworks/pull/312)) by @scode2277 +- Add branch-aware robots.txt ([#330](https://github.com/security-alliance/frameworks/pull/330)) by @scode2277 +- Add meta descriptions to every page for SEO enhancement ([#324](https://github.com/security-alliance/frameworks/pull/324)) by @scode2277 +- Bump up react-router-dom dep ([#341](https://github.com/security-alliance/frameworks/pull/341)) by @scode2277 +- adding custom 404 that doesn't redirect ([#327](https://github.com/security-alliance/frameworks/pull/327)) by @scode2277 +- Badge system for contributors ([#346](https://github.com/security-alliance/frameworks/pull/346)) by @scode2277 +- Fix/twitter preview image (it gets cropped when linking) ([#347](https://github.com/security-alliance/frameworks/pull/347)) by @scode2277 +- Making the searchbar indexer not run in local builds ([#348](https://github.com/security-alliance/frameworks/pull/348)) by @scode2277 +- weekly spellchecker + linter outputs fix ([#322](https://github.com/security-alliance/frameworks/pull/322)) by @scode2277 +- Chore: style fixes for toc and sidebar + contributing files sync ([#353](https://github.com/security-alliance/frameworks/pull/353)) by @scode2277 +- Chore: Add workflow to remind contributors to update vocs.config.ts ([#358](https://github.com/security-alliance/frameworks/pull/358)) by @scode2277 +- feat: add printable checklists for SFC certifications ([#320](https://github.com/security-alliance/frameworks/pull/320)) by @madjin +- Update vocs.config.ts to explore frameworks and outline collapsed or not ([#368](https://github.com/security-alliance/frameworks/pull/368)) by @mattaereal +- Update wordlist.txt by @mattaereal +- Add reauthentication to wordlist.txt by @mattaereal +- Chore: add sitemap.xml ([#371](https://github.com/security-alliance/frameworks/pull/371)) by @scode2277 +- Update styles.css by @mattaereal +- Chore: fix spellcheck + linter outputs, sync indexes, sync tags, sync badges ([#374](https://github.com/security-alliance/frameworks/pull/374)) by @scode2277 +- Chore: add canonical tags ([#383](https://github.com/security-alliance/frameworks/pull/383)) by @scode2277 +- Enhancement: Extending sidebar reminder to work on PRs from forks too by using pull_request_target ([#373](https://github.com/security-alliance/frameworks/pull/373)) by @scode2277 +- chore: migrate preview deployments from Vercel to Cloudflare Pages via GitHub Actions ([#395](https://github.com/security-alliance/frameworks/pull/395)) by @scode2277 +- Chore: Remove production workflow as it works with the git integration ([#402](https://github.com/security-alliance/frameworks/pull/402)) by @scode2277 +- feat(certs): Export All Certifications button on overview page ([#378](https://github.com/security-alliance/frameworks/pull/378)) by @artemisclaw82 +- Chore: weekly repo cleanup ([#413](https://github.com/security-alliance/frameworks/pull/413)) by @scode2277 +- Chore: Bump vocs to fix sidebar sections not opening on internal links ([#414](https://github.com/security-alliance/frameworks/pull/414)) by @scode2277 + +### Fixes + +- Fix logo path in README.md ([#237](https://github.com/security-alliance/frameworks/pull/237)) by @scode2277 +- fix: CONTRIBUTING.md + contributing.mdx ([#250](https://github.com/security-alliance/frameworks/pull/250)) by @scode2277 +- fix(flickering on reload): remove redirects from vercel.json ([#249](https://github.com/security-alliance/frameworks/pull/249)) by @scode2277 +- chore: add temporary patch for Vocs search indexing issue ([#257](https://github.com/security-alliance/frameworks/pull/257)) by @scode2277 +- fix: branch-related files ([#259](https://github.com/security-alliance/frameworks/pull/259)) by @scode2277 +- fix: remove duplicate framework from sidebar ([#262](https://github.com/security-alliance/frameworks/pull/262)) by @scode2277 +- Fix/markdown lint outputs ([#271](https://github.com/security-alliance/frameworks/pull/271)) by @scode2277 +- Fix/dickson slug in infra framework ([#285](https://github.com/security-alliance/frameworks/pull/285)) by @scode2277 +- fixing spotlight zone ([#311](https://github.com/security-alliance/frameworks/pull/311)) by @scode2277 +- Restore automated tag colors and fix broken link ([#310](https://github.com/security-alliance/frameworks/pull/310)) by @scode2277 +- fix md-linter path in the github workflow ([#331](https://github.com/security-alliance/frameworks/pull/331)) by @scode2277 +- Remove misadded files ([#338](https://github.com/security-alliance/frameworks/pull/338)) by @scode2277 +- fix: restore Tailwind usage for Certs components after vocs upgrade ([#354](https://github.com/security-alliance/frameworks/pull/354)) by @scode2277 +- Chore: fix index generator titles/ordering + update fetched tags ([#352](https://github.com/security-alliance/frameworks/pull/352)) by @scode2277 +- Fix double title suffix by adding titleTemplate config ([#361](https://github.com/security-alliance/frameworks/pull/361)) by @smagdali +- Grammar fix on-chain-adoption-guide.mdx by @mattaereal +- Rename files with '&' to 'and' for URL compatibility ([#372](https://github.com/security-alliance/frameworks/pull/372)) by @smagdali +- Fix: vocs.config path in index generator + added more in depth escapes for ts syntax ([#394](https://github.com/security-alliance/frameworks/pull/394)) by @scode2277 +- Revert "chore(deps): bump the npm_and_yarn group across 1 directory with 2 updates" ([#426](https://github.com/security-alliance/frameworks/pull/426)) by @mattaereal +- Fix indentation for fact-check contributor entry ([#427](https://github.com/security-alliance/frameworks/pull/427)) by @mattaereal +- Fix typos across docs ([#415](https://github.com/security-alliance/frameworks/pull/415)) by @DicksonWu654 + +### Certifications + +- SEAL Certifications incorporation, including 5 certs ([#294](https://github.com/security-alliance/frameworks/pull/294)) by @Robert-MacWha +- Certs fix: adding current status to overview and minor typos/grammar improvements ([#296](https://github.com/security-alliance/frameworks/pull/296)) by @DicksonWu654 +- Certs fix: Updating certified partners ([#297](https://github.com/security-alliance/frameworks/pull/297)) by @DicksonWu654 +- Create Devops Cert & Updating 2 other Certs ([#304](https://github.com/security-alliance/frameworks/pull/304)) by @DicksonWu654 +- Revert "Create Devops Cert & Updating 2 other Certs" ([#317](https://github.com/security-alliance/frameworks/pull/317)) by @DicksonWu654 +- Certs: Changes to Multisig Cert from Auditor's Feedback ([#339](https://github.com/security-alliance/frameworks/pull/339)) by @DicksonWu654 +- Certs: SFC DNS fixes based on feedback ([#340](https://github.com/security-alliance/frameworks/pull/340)) by @DicksonWu654 +- Cert Multisig Updates ([#362](https://github.com/security-alliance/frameworks/pull/362)) by @DicksonWu654 +- Certs Incident Response update ([#363](https://github.com/security-alliance/frameworks/pull/363)) by @DicksonWu654 +- Certs DNS Update ([#364](https://github.com/security-alliance/frameworks/pull/364)) by @DicksonWu654 +- Certs treasury ops update ([#365](https://github.com/security-alliance/frameworks/pull/365)) by @DicksonWu654 +- Certs workspace update ([#366](https://github.com/security-alliance/frameworks/pull/366)) by @DicksonWu654 +- Certs devops update ([#367](https://github.com/security-alliance/frameworks/pull/367)) by @DicksonWu654 + +### Other + +Everything below is the history up to the migration to Vocs: the original mdBook version of the site, the tagging and theming work, and the early framework drafts. Preserved in full since this is our first release. + +
+Full pre-workflow history (expand) + +- Initial commit privs by @mattaereal +- Working vanilla mdBook with catpuccino, and admonish by @mattaereal +- Hardcoding /book/ path as path_root to fix theme. Adding vercel config locally by @mattaereal +- Initial PoC structure. by @mattaereal +- Update structure by @mattaereal +- Creation of develop branch to run mdbook serve locally by @mattaereal +- Update gitignore by @mattaereal +- Hardcoding path again, after ignoring index.hbs. Should not be modified again unless necessary. by @mattaereal +- Update in structure by @mattaereal +- README.md contents, with installation and collaboration guidelines by @mattaereal +- Update issue templates by @mattaereal +- Workaround to develop on vercel as well as locally using serve.sh by @mattaereal +- Removing serve.sh workaround since develop deployment can be accessed via vercel sharing by @mattaereal +- Test to see vercel deployment develop sharing by @mattaereal +- Test to see vercel deployment develop sharing by @mattaereal +- trg intro test by @mattaereal +- SEAL intro update by @mattaereal +- What is it or isn't by @mattaereal +- README update and minor updates to intro section. by @mattaereal +- Major update with a lot of content. Some imgs are broken, need to be fixed. by @mattaereal +- Adding a way to load the logo over the ToC by @mattaereal +- Update SUMMARY.md by @0xFredrik +- Minor fixes by @0xFredrik +- Update awareness/README.md by @0xFredrik +- Update security-training.md by @0xFredrik +- Update social-engineering.md by @0xFredrik +- Update staying-up-to-date.md by @0xFredrik +- Update integrated-development-environments.md by @0xFredrik +- Create security-testing.md by @0xFredrik +- Update README.md by @0xFredrik +- Update cloud-data-encryption.md by @0xFredrik +- Create encryption-in-transit.md by @0xFredrik +- Update database-encryption.md by @0xFredrik +- Update email-encryption.md by @0xFredrik +- Update file-encryption.md by @0xFredrik +- Update full-disk-encryption.md by @0xFredrik +- Update hardware-encryption.md by @0xFredrik +- Update communication-encryption.md by @0xFredrik +- Update communication-encryption.md by @0xFredrik +- Update README.md by @0xFredrik +- Delete src/encryption/volume-encryption.md by @0xFredrik +- Update security-policies-procedures.md by @0xFredrik +- Update README.md by @0xFredrik +- Update mobile-application-security.md by @0xFredrik +- Create common-vulnerabilities.md by @0xFredrik +- Create security-tools-resources.md by @0xFredrik +- Update README.md by @0xFredrik +- Update compliance-regulatory-requirements.md by @0xFredrik +- Update risk-management.md by @0xFredrik +- Update security-metrics-kpis.md by @0xFredrik +- Update README.md by @0xFredrik +- Update role-based-access-control.md by @0xFredrik +- Update secure-authentication.md by @0xFredrik +- Create access-management-best-practises.md by @0xFredrik +- Update README.md by @0xFredrik +- Update communication-strategies.md by @0xFredrik +- Update incident-detection-and-response-mechanisms.md by @0xFredrik +- Update lessons-learned.md by @0xFredrik +- Update playbooks.md by @0xFredrik +- Update seal-911-war-room-guidelines.md by @0xFredrik +- Update zero-trust-principles.md by @0xFredrik +- Update hardware-wallets.md by @0xFredrik +- Update software-wallets.md by @0xFredrik +- Update README.md by @0xFredrik +- Update guidelines.md by @0xFredrik +- Update thresholds.md by @0xFredrik +- Update detecting-and-mitigating-insider-threats.md by @0xFredrik +- Update g-suite-security.md by @0xFredrik +- Update physical-security.md by @0xFredrik +- Update standard-operating-environment.md by @0xFredrik +- Update wireless-security.md by @0xFredrik +- Update README.md by @0xFredrik +- Update bug-bounties.md by @0xFredrik +- Update security-contact.md by @0xFredrik +- Update README.md by @0xFredrik +- Update data-removal-services.md by @0xFredrik +- Update digital-footprint.md by @0xFredrik +- Update financial-privacy-services.md by @0xFredrik +- Update privacy-focused-operating-systems-tools.md by @0xFredrik +- Update secure-browsing.md by @0xFredrik +- Update vpn-services.md by @0xFredrik +- Update README.md by @0xFredrik +- Update code-reviews-peer-audits.md by @0xFredrik +- Update secure-code-repositories-version-control.md by @0xFredrik +- Update secure-coding-standards-guidelines.md by @0xFredrik +- Update threat-modeling-secure-design-principles.md by @0xFredrik +- Update secure-code-repositories-version-control.md by @0xFredrik +- Update README.md by @0xFredrik +- Update compliance-checks.md by @0xFredrik +- Update infrastructure-as-code.md by @0xFredrik +- Update README.md by @0xFredrik +- Update dynamic-application-security-testing.md by @0xFredrik +- Update fuzz-testing.md by @0xFredrik +- Update security-regression-testing.md by @0xFredrik +- Update static-application-security-testing.md by @0xFredrik +- Update README.md by @0xFredrik +- Update dependency-awareness.md by @0xFredrik +- Update supply-chain-levels-software-artifacts.md by @0xFredrik +- Update README.md by @0xFredrik +- Update create-maintain-threat-models.md by @0xFredrik +- Update identity-mitigate-threats.md by @0xFredrik +- Update README.md by @0xFredrik +- Update phishing-social-engineering.md by @0xFredrik +- Update security-aware-culture.md by @0xFredrik +- Update security-training.md by @0xFredrik +- Adding a minimalistic crisis handbook by @mattaereal +- discord.md updates by @0xFredrik +- added self audit so it's aligned with the other community management docs by @0xFredrik +- google.md updates by @0xFredrik +- devsecops readme.md update by @0xFredrik +- Update code-signing.md by @0xFredrik +- Update continuous-integration-continuous-deployment.md by @0xFredrik +- Update repository-hardening.md by @0xFredrik +- Delete src/encryption/partition-encryption.md by @0xFredrik +- Update expectation.md by @0xFredrik +- Update preparation.md by @0xFredrik +- Update vendor-selection.md by @0xFredrik +- Update web-application-security.md by @0xFredrik +- Update how-to-navigate-the-website.md by @0xFredrik +- Update introduction.md by @0xFredrik +- Update overview-of-each-framework.md by @0xFredrik +- Update what-is-it.md by @0xFredrik +- Update what-it-isnt.md by @0xFredrik +- Delete src/infrastructure/identity-and-access-management.md by @0xFredrik +- Update README.md by @0xFredrik +- Update asset-inventory.md by @0xFredrik +- Update cloud.md by @0xFredrik +- Update ddos-protection.md by @0xFredrik +- Update dns-and-domain-registration.md by @0xFredrik +- Update network-security.md by @0xFredrik +- Update README.md by @0xFredrik +- Update cold-vs-hot-wallet.md by @0xFredrik +- Update custodial-vs-non-custodial.md by @0xFredrik +- Update signing-schemes.md by @0xFredrik +- Update README.md by @0xFredrik +- Update password-secrets-management.md by @0xFredrik +- Delete src/operational-security/telegram.md by @0xFredrik +- Delete src/privacy/encrypted-communication-tools.md by @0xFredrik +- Delete src/security-automation/threat-detection-response.md by @0xFredrik +- Update operating-system-security.md by @0xFredrik +- Update operating-system-security.md by @0xFredrik +- Update README.md by @0xFredrik +- Update README.md by @0xFredrik +- Update sim-swapping.md by @0xFredrik +- Update sim-swapping.md by @0xFredrik +- Update README.md by @0xFredrik +- Update README.md by @0xFredrik +- Update README.md by @0xFredrik +- Update README.md by @0xFredrik +- Update security-training.md by @0xFredrik +- Update social-engineering.md by @0xFredrik +- Update staying-up-to-date.md by @0xFredrik +- Update README.md by @0xFredrik +- Update discord.md by @0xFredrik +- Update google.md by @0xFredrik +- Update telegram.md by @0xFredrik +- Update twitter.md by @0xFredrik +- Update README.md by @0xFredrik +- Update code-signing.md by @0xFredrik +- Update continuous-integration-continuous-deployment.md by @0xFredrik +- Update integrated-development-environments.md by @0xFredrik +- Update repository-hardening.md by @0xFredrik +- Update security-testing.md by @0xFredrik +- Update repository-hardening.md by @0xFredrik +- Update introduction.md by @0xFredrik +- Update what-is-it.md by @0xFredrik +- Update README.md by @0xFredrik +- Update cloud-data-encryption.md by @0xFredrik +- Update database-encryption.md by @0xFredrik +- Update email-encryption.md by @0xFredrik +- Update encryption-in-transit.md by @0xFredrik +- Update full-disk-encryption.md by @0xFredrik +- Update hardware-encryption.md by @0xFredrik +- Update guidelines.md by @0xFredrik +- Update thresholds.md by @0xFredrik +- Update README.md by @0xFredrik +- Update compliance-checks.md by @0xFredrik +- Update infrastructure-as-code.md by @0xFredrik +- Update standard-operating-environment.md by @0xFredrik +- Update expectation.md by @0xFredrik +- Update preparation.md by @0xFredrik +- Update security-policies-procedures.md by @0xFredrik +- Update vendor-selection.md by @0xFredrik +- Update README.md by @0xFredrik +- Update common-vulnerabilities.md by @0xFredrik +- Update mobile-application-security.md by @0xFredrik +- Update security-tools-resources.md by @0xFredrik +- Update web-application-security.md by @0xFredrik +- Update README.md by @0xFredrik +- Update compliance-regulatory-requirements.md by @0xFredrik +- Update risk-management.md by @0xFredrik +- Update security-metrics-kpis.md by @0xFredrik +- Update README.md by @0xFredrik +- Update access-management-best-practises.md by @0xFredrik +- Update role-based-access-control.md by @0xFredrik +- Update secure-authentication.md by @0xFredrik +- Update README.md by @0xFredrik +- Update communication-strategies.md by @0xFredrik +- Update incident-detection-and-response-mechanisms.md by @0xFredrik +- Update lessons-learned.md by @0xFredrik +- Update playbooks.md by @0xFredrik +- Update README.md by @0xFredrik +- Update asset-inventory.md by @0xFredrik +- Update cloud.md by @0xFredrik +- Update ddos-protection.md by @0xFredrik +- Update dns-and-domain-registration.md by @0xFredrik +- Update network-security.md by @0xFredrik +- Update operating-system-security.md by @0xFredrik +- Update zero-trust-principles.md by @0xFredrik +- Update cold-vs-hot-wallet.md by @0xFredrik +- Update custodial-vs-non-custodial.md by @0xFredrik +- Update signing-schemes.md by @0xFredrik +- Update software-wallets.md by @0xFredrik +- Update README.md by @0xFredrik +- Update bug-bounties.md by @0xFredrik +- Update security-contact.md by @0xFredrik +- Update create-maintain-threat-models.md by @0xFredrik +- Update README.md by @0xFredrik +- Update phishing-social-engineering.md by @0xFredrik +- Update security-aware-culture.md by @0xFredrik +- Update security-training.md by @0xFredrik +- Update README.md by @0xFredrik +- Update dependency-awareness.md by @0xFredrik +- Update supply-chain-levels-software-artifacts.md by @0xFredrik +- Update README.md by @0xFredrik +- Update dynamic-application-security-testing.md by @0xFredrik +- Update security-regression-testing.md by @0xFredrik +- Update README.md by @0xFredrik +- Update code-reviews-peer-audits.md by @0xFredrik +- Update secure-code-repositories-version-control.md by @0xFredrik +- Update secure-coding-standards-guidelines.md by @0xFredrik +- Update threat-modeling-secure-design-principles.md by @0xFredrik +- Update README.md by @0xFredrik +- Update data-removal-services.md by @0xFredrik +- Update digital-footprint.md by @0xFredrik +- Update financial-privacy-services.md by @0xFredrik +- Update privacy-focused-operating-systems-tools.md by @0xFredrik +- Update secure-browsing.md by @0xFredrik +- Update vpn-services.md by @0xFredrik +- Update README.md by @0xFredrik +- Update detecting-and-mitigating-insider-threats.md by @0xFredrik +- Update g-suite-security.md by @0xFredrik +- Update password-secrets-management.md by @0xFredrik +- Update physical-security.md by @0xFredrik +- Update standard-operating-environment.md by @0xFredrik +- Update wireless-security.md by @0xFredrik +- Update mobile-application-security.md by @0xFredrik +- Update email-encryption.md by @0xFredrik +- Update web-application-security.md by @0xFredrik +- Update secure-code-repositories-version-control.md by @0xFredrik +- Update security-training.md by @0xFredrik +- Update social-engineering.md by @0xFredrik +- Update lessons-learned.md by @0xFredrik +- Update communication-strategies.md by @0xFredrik +- Update full-disk-encryption.md by @0xFredrik +- Update software-wallets.md by @0xFredrik +- Create CODE_OF_CONDUCT.md by @0xFredrik +- Update .gitignore by @0xFredrik +- Create md-lint.yaml by @0xFredrik +- Create spell-check.yml by @0xFredrik +- Create PULL_REQUEST_TEMPLATE.md by @0xFredrik +- Create wordlist.txt by @0xFredrik +- Create content-request.md by @0xFredrik +- Create contributing.md by @0xFredrik +- Update SUMMARY.md by @0xFredrik +- Update contributing.md by @0xFredrik +- Update contributing.md by @0xFredrik +- Update README.md by @0xFredrik +- Update README.md by @0xFredrik +- Update security-training.md by @0xFredrik +- Update social-engineering.md by @0xFredrik +- Update staying-up-to-date.md by @0xFredrik +- Update SUMMARY.md by @0xFredrik +- Update SUMMARY.md by @0xFredrik +- Delete src/misc/contributors.md by @0xFredrik +- Moving contributors.md into contribute folder by @0xFredrik +- Update introduction.md by @0xFredrik +- Update README.md by @0xFredrik +- Update security-training.md by @0xFredrik +- Update social-engineering.md by @0xFredrik +- Update staying-up-to-date.md by @0xFredrik +- Update contributing.md by @0xFredrik +- Update introduction.md by @0xFredrik +- Update contributing.md by @0xFredrik +- Stage 2 of merge by @mattaereal +- Update content-request.md by @mattaereal +- Create update-request.md by @mattaereal +- Update content-request.md by @mattaereal +- Update update-request.md by @mattaereal +- Added suggested feedback for compliance, IAM, how to navigate the website, and more. by @mattaereal +- Update seal-911-war-room-guidelines.md by @mattaereal +- Added the correct path to the contribution page. by @mattaereal +- Feedback applied to passwords, SE, and security training. by @mattaereal +- Update README.md with recent changes to collaboration and local setup instructions by @mattaereal +- Updated build setup to newest version by @mattaereal +- Improved best practices on email encryption by @mattaereal +- Improved best practices on cloud encryption by @mattaereal +- Modified serve.sh script to be compatible with macos by @tebayoso +- Tags working by @tebayoso +- Added serve and build specs by @tebayoso +- Cleaned up eol by @tebayoso +- Added EOL to editorconfig by @tebayoso +- Upgraded vercel build by @tebayoso +- Added sample tags to each page, improved serve.sh script, and updated various documentation files to enhance clarity and completeness by @mattaereal +- Modified gitignore to accept handlebars index. by @mattaereal +- Changed URLS and minor typo on serve script. by @mattaereal +- Trying a new way to deploy to get rid of a hardcoding workaround on index.hbs by @mattaereal +- Trying a new vercel.json config by @mattaereal +- Deprecating previous replacement with sed on serve.sh by @mattaereal +- Removing old /book path from url on README.md by @mattaereal +- Updating readme to match current local setup by @mattaereal +- Added improved tag images by @tebayoso +- Tags Colors working by @tebayoso +- Fix wordlist.txt by @0xFredrik +- Added collaborate stripe by @tebayoso +- Updating current tags to incorporate HR, and a few more by @mattaereal +- Improvemets in tag selection and announcement banner by @tebayoso +- Clear tags and filters by @tebayoso +- Update theme/index.hbs by @tebayoso +- fix typos by @zedt3ster +- expand wordlist and order alphabetically by @zedt3ster +- more word exclusions by @zedt3ster +- more typo fixes by @zedt3ster +- more typo fixes by @zedt3ster +- Updating wordlist.txt and some markdown linting fixes by @mattaereal +- Jump of line fix in README by @mattaereal +- Updating wordlist by @mattaereal +- docs: Update README ##pull-requests by @Robert-MacWha +- fix: Fix typo by @Robert-MacWha +- fix: typos in pr_template by @Robert-MacWha +- add SEAL logo as favicon by @zedt3ster +- feat: improved tag generation by @Robert-MacWha +- feat: Update tag display system by @Robert-MacWha +- feat: remove duplicate code & document methods by @Robert-MacWha +- refactor: move JS and CSS to seperate files by @Robert-MacWha +- style: Added margin around page-tags by @Robert-MacWha +- refactor: Extract tag initialization logic into seperate methods by @Robert-MacWha +- fix: announcement-stripe overflowing at lower horizontal resolutions by @Robert-MacWha +- feat: implemented AND selection for tags. by @Robert-MacWha +- feat: remove HTML styling on tag-search by @Robert-MacWha +- Adding a few more words to wordlist.txt by @mattaereal +- feat: Bookmarks ([#83](https://github.com/security-alliance/frameworks/pull/83)) by @Robert-MacWha +- Safe Harbor Docs ([#92](https://github.com/security-alliance/frameworks/pull/92)) by @Robert-MacWha +- Add yaml frontmatter & build time tags ([#102](https://github.com/security-alliance/frameworks/pull/102)) by @Robert-MacWha +- Adding .code-workspace to gitignore by @mattaereal +- Merge from develop ([#85](https://github.com/security-alliance/frameworks/pull/85)) by @mattaereal +- Changing default theme to navy by @mattaereal +- First commit for this framework. Introduction refactored. by @mattaereal +- Discord update, with ToC by @mattaereal +- X (Twitter) update, with ToC by @mattaereal +- Normalizing summary.md by @mattaereal +- Updating Telegram, also a ToC and MITM attack by @mattaereal +- Updating Google, added ToC, and SUMMARY by @mattaereal +- Normalizing dividers by @mattaereal +- Minor modifications, reordering SUMMARY by @mattaereal +- Update src/community-management/README.md by @mattaereal +- Update src/community-management/README.md by @mattaereal +- Added key takeaways and improved some wording. by @mattaereal +- Trying JoreAli's mdBook pagetoc by @mattaereal +- feat: fix toc and package theme into "toc" folder ([#100](https://github.com/security-alliance/frameworks/pull/100)) by @Robert-MacWha +- Update spell-check.yml by @mattaereal +- Update discord.md by @NFTDreww +- Update google.md by @NFTDreww +- Update telegram.md by @NFTDreww +- Update twitter.md by @NFTDreww +- Improved formatting and summarized contents by @mattaereal +- Improved formatting and summarized contents (google) by @mattaereal +- Improved formatting and summarized contents (telegram) by @mattaereal +- Improved formatting and summarized contents (X) by @mattaereal +- Fw community mgmt ([#99](https://github.com/security-alliance/frameworks/pull/99)) by @NFTDreww +- Solving conflicts from previous merge by @mattaereal +- Solving more conflicts from previous merge. My ide messed up something by @mattaereal +- Adding following banner, improved ToC, footer, and more by @mattaereal +- Normalizing platform contents for comm mgmt by @mattaereal +- update telegram session management instructions ([#104](https://github.com/security-alliance/frameworks/pull/104)) by @matt-dragonfly +- Removing remove from toc title for twitter by @mattaereal +- Tweaked footer by @mattaereal +- Adding conditional banner, and prebuild to change SUMMARY depending on branch. by @mattaereal +- Testing pre-build run on develop by @mattaereal +- Merge from develop, testing conditional banner by @mattaereal +- Merge from develop! New stage. ([#111](https://github.com/security-alliance/frameworks/pull/111)) by @mattaereal +- Updating summary by @mattaereal +- Merge prebuild-summary into develop ([#114](https://github.com/security-alliance/frameworks/pull/114)) by @mattaereal +- Merge prebuild-summary into develop ([#116](https://github.com/security-alliance/frameworks/pull/116)) by @mattaereal +- Updating prebuild.sh to work with vercel's config and fixing grammar ([#117](https://github.com/security-alliance/frameworks/pull/117)) by @mattaereal +- Merge prebuild-summary into develop ([#118](https://github.com/security-alliance/frameworks/pull/118)) by @mattaereal +- Contributors first run by @mattaereal +- Tags and Contributors plugin merge into mdbook-metadata, plus an example by @mattaereal +- Cleaned contributors plugin, removing unused code by @mattaereal +- Fix broken link by @engn33r +- Updating spellcheck wordlist.txt by @mattaereal +- Updating spellcheck wordlist.txt (removing invalid character by @mattaereal +- Updating spellcheck wordlist.txt (adding draww again). This spellcheck I swear to god... by @mattaereal +- Initial commit for this updated framework by @mattaereal +- Adding new words to wordlist by @mattaereal +- Merging user-team-security into awareness, at least for now. A lot of overlap by @mattaereal +- Updating summary to remove user-team-security by @mattaereal +- Proof reading and improving current contents with Claude. Adding Key takeaways. by @mattaereal +- Removing user-team-security folder, no longer needed after merging it with awareness. by @mattaereal +- Added prebuild.sh to vercel_build and updated Summaries. by @mattaereal +- Updating prebuild to work in vercel for dynamic summaries. by @mattaereal +- Updating wordlist as well for summaries by @mattaereal +- Updating wordlist by @mattaereal +- Updating prebuild config. by @mattaereal +- Restructuring contributors and tags generation by @mattaereal +- Improving the format of contributors on the contributing final list by @mattaereal +- Forgot to keep track of these files on the previous commit. by @mattaereal +- Moved CSS from within rust to actual CSS/HTML files, with a fallback in rust for some themes, but mainly files. by @mattaereal +- Fix announcement banner width ([#131](https://github.com/security-alliance/frameworks/pull/131)) by @davidthegardens +- feat: remove banner from production site ([#133](https://github.com/security-alliance/frameworks/pull/133)) by @Robert-MacWha +- chore: update Cargo.lock for mdbook-metadata plugin by @mattaereal +- Updating contributions by @mattaereal +- Contributors style and formatting upgrade ([#136](https://github.com/security-alliance/frameworks/pull/136)) by @mattaereal +- Minor theme fix, bullets on outline by @mattaereal +- Updated contributor list with correct information by @mattaereal +- Merging develop from mdbook-contributors ([#138](https://github.com/security-alliance/frameworks/pull/138)) by @mattaereal +- Ens best practices ([#139](https://github.com/security-alliance/frameworks/pull/139)) by @Ghadi8 +- ENS, Awareness, Summaries and Contributors hygiene. by @mattaereal +- Removing track of contributorsindex and tagsindex by @mattaereal +- Code review additions ([#145](https://github.com/security-alliance/frameworks/pull/145)) by @ElliotFriedman +- Updated contributing and readme.md by @mattaereal +- Removed catpuccin, updated mdbook and admonish. ([#147](https://github.com/security-alliance/frameworks/pull/147)) by @mattaereal +- Clean update of logo and favicon. ([#151](https://github.com/security-alliance/frameworks/pull/151)) by @mattaereal +- Updating develop to the new and more humane beginning of a written Opsec Framework ([#154](https://github.com/security-alliance/frameworks/pull/154)) by @mattaereal +- Updating Opsec with latest updates ([#157](https://github.com/security-alliance/frameworks/pull/157)) by @mattaereal +- Initial draft of personal security travel guide! ([#158](https://github.com/security-alliance/frameworks/pull/158)) by @mattaereal +- Attribution by @mattaereal +- Updating naming on opsec travel guide by @mattaereal +- Updating, and re-ordering paragraphs from opsec travel guide by @mattaereal +- Attribution to sources by @mattaereal +- Add Secure Multisig Signing Process ([#122](https://github.com/security-alliance/frameworks/pull/122)) by @engn33r +- Removing the old operational-security folder, moving secure-multisig contents within wallet-security, and re-generated the overview of frameworks with AI. by @mattaereal +- feat: Safe Harbor Framework ([#144](https://github.com/security-alliance/frameworks/pull/144)) by @Robert-MacWha +- doc: Instruction for re-writing history to sign commits ([#156](https://github.com/security-alliance/frameworks/pull/156)) by @Robert-MacWha +- Tidy plugins ([#143](https://github.com/security-alliance/frameworks/pull/143)) by @Robert-MacWha +- feat: overhaul of the Wallet Security section ([#164](https://github.com/security-alliance/frameworks/pull/164)) by @pinalikefruit +- feat: fix extra fields & add verbose errors ([#167](https://github.com/security-alliance/frameworks/pull/167)) by @Robert-MacWha +- Fix several misc ([#168](https://github.com/security-alliance/frameworks/pull/168)) by @mattaereal +- Removing spell-check from develop. Only on main from now on. Exploratory. by @mattaereal +- feat: security testing - solidity focused ([#163](https://github.com/security-alliance/frameworks/pull/163)) by @PatrickAlphaC +- Introducing Decentralized IR Framework ([#165](https://github.com/security-alliance/frameworks/pull/165)) by @relotnek +- feat: external security reviews & patrick addition ([#160](https://github.com/security-alliance/frameworks/pull/160)) by @PatrickAlphaC +- Adding to the outline the latest pushed content. by @mattaereal +- Bump mdbook version ([#177](https://github.com/security-alliance/frameworks/pull/177)) by @davidthegardens +- feat: added more information on wallet security ([#173](https://github.com/security-alliance/frameworks/pull/173)) by @PatrickAlphaC +- Update PULL_REQUEST_TEMPLATE.md ([#174](https://github.com/security-alliance/frameworks/pull/174)) by @mattaereal +- fix: stewards ([#172](https://github.com/security-alliance/frameworks/pull/172)) by @PatrickAlphaC +- Update tldr.md ([#181](https://github.com/security-alliance/frameworks/pull/181)) by @NFTDreww +- Update README.md ([#178](https://github.com/security-alliance/frameworks/pull/178)) by @GodwinDA +- Update implementation-process.md ([#179](https://github.com/security-alliance/frameworks/pull/179)) by @GodwinDA +- feat: updating linting, devcontainer, and local development ([#184](https://github.com/security-alliance/frameworks/pull/184)) by @PatrickAlphaC +- Going back to 0.4.40 stable. by @mattaereal +- Fix spelling issues and update wordlist ([#188](https://github.com/security-alliance/frameworks/pull/188)) by @mattaereal +- Fix typos in mdbook-metadata README.md and add renderer to wordlist by @mattaereal +- Update threat-modeling-overview.md ([#182](https://github.com/security-alliance/frameworks/pull/182)) by @damboy0 +- Updating Safe Harbor Documentation ([#186](https://github.com/security-alliance/frameworks/pull/186)) by @DicksonWu654 +- Updating outlines. Removing empty frameworks from main by @mattaereal +- Fixing broken link in PR template by @mattaereal +- Fixing grammar issues and spellcheck by @mattaereal +- 3 frameworks, contributors and spellcheck (Wallet Security, External Security Reviews, and Security Testing frameworks) ([#187](https://github.com/security-alliance/frameworks/pull/187)) by @mattaereal +- feat: handle reverse records per chain ([#199](https://github.com/security-alliance/frameworks/pull/199)) by @Ghadi8 +- Update Safe Harbor documentation for clarity and consistency ([#195](https://github.com/security-alliance/frameworks/pull/195)) by @DicksonWu654 +- Fix cross-site image loading issues ([#200](https://github.com/security-alliance/frameworks/pull/200)) by @Robert-MacWha +- quick fix for external security reviews by @mattaereal +- Fixed DevContainer Issue + github cli + Updated Documentation + Pre-build docker image ([#198](https://github.com/security-alliance/frameworks/pull/198)) by @DicksonWu654 +- Update link in Identity and Access Management documentation for accuracy ([#203](https://github.com/security-alliance/frameworks/pull/203)) by @DicksonWu654 +- Update links in self-checklist.md for improved navigation ([#205](https://github.com/security-alliance/frameworks/pull/205)) by @DicksonWu654 +- feat: Add insider-threats framework (DPRK IT Workers) ([#193](https://github.com/security-alliance/frameworks/pull/193)) by @shortdoom +- Addition of a Mutation Testing Section ([#180](https://github.com/security-alliance/frameworks/pull/180)) by @nbelenkov +- docs: update wallet security resources ([#213](https://github.com/security-alliance/frameworks/pull/213)) by @pinalikefruit +- Add manual review page in External Security Reviews framework. ([#183](https://github.com/security-alliance/frameworks/pull/183)) by @the-caliber +- Update guide to put some realistic info a bout juice jacking by @mattaereal +- Updated dev ([#215](https://github.com/security-alliance/frameworks/pull/215)) by @Robert-MacWha +- Updating main on missing commits due to previous selective-merging ([#192](https://github.com/security-alliance/frameworks/pull/192)) by @mattaereal +- quick fix for external security reviews by @mattaereal +- Adding dobs suggestions by @mattaereal +- Add Yaniv Sofer as a contributor and update review roles in insider t… ([#221](https://github.com/security-alliance/frameworks/pull/221)) by @DicksonWu654 +- hotfix: fix broken summary.md.main link by @Robert-MacWha +- fix: naming change - explicit DPRK IT Workers framework ([#223](https://github.com/security-alliance/frameworks/pull/223)) by @shortdoom +- Incident management playbook ([#224](https://github.com/security-alliance/frameworks/pull/224)) by @00xWizard +- Incident management playbooks ([#233](https://github.com/security-alliance/frameworks/pull/233)) by @scode2277 +- Vocs Migration ([#227](https://github.com/security-alliance/frameworks/pull/227)) by @scode2277 + +
\ No newline at end of file diff --git a/cliff.toml b/cliff.toml index 3e6e86a5..09728320 100644 --- a/cliff.toml +++ b/cliff.toml @@ -3,15 +3,22 @@ header = """ # Changelog All notable changes to the Security Frameworks are documented here. + """ +# PR titles are contributor input and are published in the GitHub Release and on the +# site's /changelog page, so they are rendered as plain text. The template escapes < and +# > to prevent HTML tags, escapes [ and ] as entities to prevent markdown links and +# images (entities, unlike backslashes, cannot be undone by a preceding backslash), and +# inserts a zero-width space (\u200B) after @ to prevent mentions. The "-%}" markers +# produce a single blank line around headings. body = """ -{% macro remote_url() %}https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}{% endmacro %} -{% if version %} +{% macro remote_url() %}https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}{% endmacro -%} +{% if version -%} ## {{ version | trim_start_matches(pat="v") }} ({{ timestamp | date(format="%Y-%m-%d") }}) -{% else %} +{% else -%} ## Unreleased -{% endif %} +{% endif -%} {% for group, commits in commits | filter(attribute="merge_commit", value=false) | group_by(attribute="group") %} ### {{ group | striptags | trim | upper_first }} {% for commit in commits %} @@ -20,7 +27,8 @@ body = """ {%- else -%} {%- set entry = commit.message | split(pat="\n") | first -%} {%- endif %} -- {{ entry | trim }}{% if commit.remote.pr_number %} ([#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }})){% endif %}{% if commit.remote.username %} by @{{ commit.remote.username }}{% endif %} +{%- set entry = entry | trim | replace(from="<", to="<") | replace(from=">", to=">") | replace(from="[", to="[") | replace(from="]", to="]") | replace(from="@", to="@\u200B") %} +- {{ entry }}{% if commit.remote.pr_number %} ([#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }})){% endif %}{% if commit.remote.username %} by @{{ commit.remote.username }}{% endif %} {%- endfor %} {% endfor %} """ @@ -28,6 +36,9 @@ body = """ trim = true [git] +# Each run renders a single release from an explicit range. Older release tags inside +# the range, introduced by main -> develop syncs, must not split it into sections. +ignore_tags = ".*" conventional_commits = false filter_unconventional = false filter_commits = false @@ -38,12 +49,17 @@ commit_parsers = [ { message = "^Merge branch", skip = true }, { message = "^chore\\(release\\)", skip = true }, - { field = "github.pr_labels", pattern = "dependencies", skip = true }, + # Excluded from the changelog: + # release - the chore(release) PR. + # skip-changelog - any PR that should not be listed. + { field = "github.pr_labels", pattern = "^(release|skip-changelog)$", skip = true }, + { field = "github.pr_labels", pattern = "^dependencies$", skip = true }, { field = "github.pr_labels", pattern = "content:add", group = " New content" }, { field = "github.pr_labels", pattern = "content:update", group = " Updated content" }, { field = "github.pr_labels", pattern = "enhancement", group = " Enhancements" }, - { field = "github.pr_labels", pattern = "certifications", group = " Certifications" }, - + # Anchored so that it does not match "wontfix". + { field = "github.pr_labels", pattern = "^fix$", group = " Fixes" }, + { field = "github.pr_labels", pattern = "certifications", group = " Certifications" }, { message = ".*", group = " Other" }, ] \ No newline at end of file