Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9b26d6f
ci: fix updating apt dependencies
rjaegers Jan 30, 2026
7a3143f
ci: truncate release details for extension updates
rjaegers Jan 30, 2026
06c71b8
ci: fix script error
rjaegers Jan 30, 2026
041b38b
ci: minor script fixes
rjaegers Jan 30, 2026
03e6010
ci: more script fixes
rjaegers Jan 30, 2026
e67d908
ci: more fixing
rjaegers Jan 30, 2026
08cbea6
ci: minor refactor
rjaegers Jan 30, 2026
79511c9
ci: different strategy
rjaegers Jan 30, 2026
4e86f5c
ci: enable dry-run of update-dependencies jobs
rjaegers Jan 30, 2026
093d594
Update .github/workflows/update-dependencies.yml
rjaegers Jan 30, 2026
603c367
ci: revert copilot fix
rjaegers Jan 30, 2026
4f7eca2
ci: additional fixes
rjaegers Jan 30, 2026
c911e41
Merge branch 'ci/fix-update-dependencies' of https://github.com/phili…
rjaegers Jan 30, 2026
96018d6
ci: another another aproach
rjaegers Jan 30, 2026
a32cad4
ci: reduce script injection attack surface
rjaegers Jan 30, 2026
8132ded
ci: don't add files to the workspace
rjaegers Jan 30, 2026
f9114f4
chore(deps, cpp): update mull-19 (#1115)
philips-software-forest-releaser[bot] Jan 30, 2026
86a8ed8
Merge branch 'main' into ci/fix-update-dependencies
rjaegers Jan 30, 2026
cbf9234
Apply suggestion from @Copilot
rjaegers Jan 30, 2026
e612015
Apply suggestion from @rjaegers
rjaegers Jan 30, 2026
4c473df
ci: shorten job names somewhat
rjaegers Feb 2, 2026
0fca037
ci: processed review comment
rjaegers Feb 2, 2026
8e8c3ca
ci: use secure temp files
rjaegers Feb 2, 2026
d025582
ci: process more review comments
rjaegers Feb 2, 2026
adbd4a8
ci: switch to date based comparison for release notes
rjaegers Feb 2, 2026
770eb72
ci: give a visual cue of a dry-run
rjaegers Feb 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 4 additions & 10 deletions .github/actions/update-vscode-extensions/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ outputs:
updated-dependencies:
description: JSON array with the names of the updated dependencies
value: ${{ steps.update-extensions.outputs.updated-dependencies }}
markdown-summary:
description: Markdown summary of update result
value: ${{ steps.update-extensions.outputs.markdown-summary }}
markdown-summary-file:
description: Path to a file containing the markdown summary of update result
value: ${{ steps.update-extensions.outputs.markdown-summary-file }}

runs:
using: composite
Expand All @@ -24,13 +24,7 @@ runs:
sudo npm install -g @vscode/vsce
shell: bash
- run: |
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
echo "markdown-summary<<${EOF}" >> "${GITHUB_OUTPUT}"
echo "$(${GITHUB_ACTION_PATH}/update-vscode-extensions.sh ${INPUT_FILE})" >> "${GITHUB_OUTPUT}"
echo "${EOF}" >> "${GITHUB_OUTPUT}"

echo "updated-dependencies=$(cat updated-extensions.json)" >> "${GITHUB_OUTPUT}"
rm updated-extensions.json
"${GITHUB_ACTION_PATH}/update-vscode-extensions.sh" "${INPUT_FILE}"
id: update-extensions
shell: bash
env:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

set -Eeuo pipefail

FILE=${1:?}
JSON=$(cat $FILE)
FILE=${1:?"Usage: $0 <input-file>"}
JSON=$(cat "$FILE")
EXTENSIONS=
UPDATE_DETAILS_MARKDOWN=
UPDATED_EXTENSIONS_JSON="[]"
Expand All @@ -20,48 +20,74 @@ prevent_github_at_mentions() {

get_github_releasenotes() {
local GITHUB_URL=${1:?}
local CURRENT_RELEASE=${2:?}

gh release list --exclude-drafts --exclude-pre-releases -R $GITHUB_URL --json name,tagName --jq '.[]' | while read -r RELEASE;
do
NAME=$(echo "$RELEASE" | jq -r '.name')
TAG=$(echo "$RELEASE" | jq -r '.tagName')

if [[ $NAME == *$CURRENT_RELEASE* || $TAG == v$CURRENT_RELEASE ]];
then
break;
fi

printf "%s\n\n" "$(gh release view --json body --jq '.body' -R $GITHUB_URL $TAG)"
local CURRENT_VERSION_DATE=${2:?}

# Fetch all releases newer than the current version's publish date
# This approach works regardless of versioning scheme (semver, date-based, etc.)
gh release list --exclude-drafts --exclude-pre-releases -R "$GITHUB_URL" \
--json tagName,publishedAt \
--jq ".[] | select(.publishedAt > \"$CURRENT_VERSION_DATE\") | .tagName" | \
while read -r TAG; do
printf "%s\n\n" "$(gh release view --json body --jq '.body' -R "$GITHUB_URL" "$TAG")"
done
}

for EXTENSION in $(echo $JSON | jq -r '.customizations.vscode.extensions | flatten[]'); do
while IFS= read -r EXTENSION; do
[[ -z "$EXTENSION" ]] && continue

NAME="${EXTENSION%%@*}"
CURRENT_VERSION="${EXTENSION#*@}"

LATEST_NON_PRERELEASE_VERSION_JSON=$(vsce show --json $NAME | jq '[ .versions[] | select(.properties) | select(any(.properties[].key; contains("Microsoft.VisualStudio.Code.PreRelease")) | not) ][0]')
LATEST_NON_PRERELEASE_VERSION=$(echo $LATEST_NON_PRERELEASE_VERSION_JSON | jq -r '.version')
# Fetch all non-prerelease versions with their dates
ALL_VERSIONS_JSON=$(vsce show --json "$NAME" | jq '[ .versions[] | select(.properties) | select(any(.properties[].key; contains("Microsoft.VisualStudio.Code.PreRelease")) | not) ]')
LATEST_NON_PRERELEASE_VERSION_JSON=$(echo "$ALL_VERSIONS_JSON" | jq '.[0]')
LATEST_NON_PRERELEASE_VERSION=$(echo "$LATEST_NON_PRERELEASE_VERSION_JSON" | jq -r '.version')

if [[ $CURRENT_VERSION != $LATEST_NON_PRERELEASE_VERSION ]];
if [[ $CURRENT_VERSION != "$LATEST_NON_PRERELEASE_VERSION" ]];
then
GITHUB_URL=$(echo $LATEST_NON_PRERELEASE_VERSION_JSON | jq -r '.properties | map(select(.key == "Microsoft.VisualStudio.Services.Links.GitHub"))[] | .value')
GITHUB_URL=$(echo "$LATEST_NON_PRERELEASE_VERSION_JSON" | jq -r '.properties | map(select(.key == "Microsoft.VisualStudio.Services.Links.GitHub"))[] | .value')

if [[ -n "$GITHUB_URL" && "$GITHUB_URL" != "null" ]]; then
RELEASE_DETAILS=$(get_github_releasenotes $GITHUB_URL $CURRENT_VERSION | prevent_github_backlinks | prevent_github_at_mentions)
UPDATE_DETAILS_MARKDOWN=$(printf "Updates \`%s\` from %s to %s\n<details>\n<summary>Release notes</summary>\n<blockquote>\n\n%s\n</blockquote>\n</details>\n\n%s" $NAME $CURRENT_VERSION $LATEST_NON_PRERELEASE_VERSION "$RELEASE_DETAILS" "$UPDATE_DETAILS_MARKDOWN")
# Get the publish date of the current version for date-based release matching
CURRENT_VERSION_DATE=$(echo "$ALL_VERSIONS_JSON" | jq -r --arg version "$CURRENT_VERSION" 'map(select(.version == $version))[0].lastUpdated // empty')

if [[ -n "$CURRENT_VERSION_DATE" ]]; then
RELEASE_DETAILS=$(get_github_releasenotes "$GITHUB_URL" "$CURRENT_VERSION_DATE" | prevent_github_backlinks | prevent_github_at_mentions)
else
echo "::warning::Could not find publish date for $NAME@$CURRENT_VERSION, skipping release notes"
RELEASE_DETAILS=""
fi
UPDATE_DETAILS_MARKDOWN=$(printf "Updates \`%s\` from %s to %s\n<details>\n<summary>Release notes</summary>\n<blockquote>\n\n%s\n</blockquote>\n</details>\n\n%s" "$NAME" "$CURRENT_VERSION" "$LATEST_NON_PRERELEASE_VERSION" "$RELEASE_DETAILS" "$UPDATE_DETAILS_MARKDOWN")
else
UPDATE_DETAILS_MARKDOWN=$(printf "Updates \`%s\` from %s to %s\n\n%s" $NAME $CURRENT_VERSION $LATEST_NON_PRERELEASE_VERSION "$UPDATE_DETAILS_MARKDOWN")
UPDATE_DETAILS_MARKDOWN=$(printf "Updates \`%s\` from %s to %s\n\n%s" "$NAME" "$CURRENT_VERSION" "$LATEST_NON_PRERELEASE_VERSION" "$UPDATE_DETAILS_MARKDOWN")
fi

UPDATED_EXTENSIONS_JSON=$(echo $UPDATED_EXTENSIONS_JSON | jq -c '. += ["'$NAME'"]')
UPDATED_EXTENSIONS_JSON=$(echo "$UPDATED_EXTENSIONS_JSON" | jq -c --arg name "$NAME" '. += [$name]')
fi

EXTENSIONS="\"$NAME@$LATEST_NON_PRERELEASE_VERSION\",$EXTENSIONS"
done
done < <(echo "$JSON" | jq -r '.customizations.vscode.extensions | flatten[]')

EXTENSIONS=$(echo "[${EXTENSIONS::-1}]" | jq 'sort_by(. | ascii_downcase)')
echo $JSON | jq '.customizations.vscode.extensions = $extensions' --argjson extensions "$EXTENSIONS" > $FILE
if [[ -n "$EXTENSIONS" ]]; then
EXTENSIONS=$(echo "[${EXTENSIONS::-1}]" | jq 'sort_by(. | ascii_downcase)')
else
EXTENSIONS="[]"
fi

echo "$JSON" | jq '.customizations.vscode.extensions = $extensions' --argjson extensions "$EXTENSIONS" > "$FILE"

echo "::group::📄 Changes to $FILE"
git diff --color=always -- "$FILE" || true
echo "::endgroup::"

echo "::group::VS Code Extensions Update Details"
echo "$UPDATE_DETAILS_MARKDOWN"
echo "$UPDATED_EXTENSIONS_JSON" > updated-extensions.json
echo "::endgroup::"

MARKDOWN_SUMMARY_FILE=$(mktemp "${RUNNER_TEMP:-/tmp}/markdown-summary.XXXXXX.md")
echo "$UPDATE_DETAILS_MARKDOWN" > "${MARKDOWN_SUMMARY_FILE}"

if [[ -n "${GITHUB_OUTPUT:-}" ]]; then
echo "markdown-summary-file=${MARKDOWN_SUMMARY_FILE}" >> "${GITHUB_OUTPUT}"
echo "updated-dependencies=${UPDATED_EXTENSIONS_JSON}" >> "${GITHUB_OUTPUT}"
fi
31 changes: 22 additions & 9 deletions .github/workflows/update-dependencies.yml
Original file line number Diff line number Diff line change
@@ -1,87 +1,100 @@
---
name: Update Dependencies
name: 📦 Update

on:
pull_request:
schedule:
- cron: "30 2 * * 0"
workflow_dispatch:

permissions: {}

jobs:
update-apt-dependencies:
name: Update APT Dependencies (🍨 ${{ matrix.flavor }})
name: ${{ github.event_name == 'pull_request' && '🧪' || '' }} OS (🍨 ${{ matrix.flavor }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
flavor: ["base", "cpp", "rust"]
# Using our own container is required since we need all package sources
# set-up correctly.
container: ghcr.io/philips-software/amp-devcontainer-${{ matrix.flavor }}:edge
permissions:
contents: write # is needed by peter-evans/create-pull-request to create branches and push commits
pull-requests: write # is needed by peter-evans/create-pull-request to create a PR
steps:
- uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
with:
egress-policy: audit
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: ./.github/actions/update-apt-packages
id: update-packages
with:
input-file: .devcontainer/${{ matrix.flavor }}/apt-requirements-*.json
input-file: .devcontainer/${{ matrix.flavor }}/apt-requirements*.json
- uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
id: token
if: github.event_name != 'pull_request'
with:
app-id: ${{ vars.FOREST_RELEASER_APP_ID }}
private-key: ${{ secrets.FOREST_RELEASER_APP_PRIVATE_KEY }}
- uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
if: github.event_name != 'pull_request'
with:
commit-message: "Update ${{ join(fromJson(steps.update-packages.outputs.updated-dependencies), ', ') }}"
branch: feature/amp-devcontainer-${{ matrix.flavor }}/update-apt-packages
title: "chore(deps, ${{ matrix.flavor }}): update ${{ join(fromJson(steps.update-packages.outputs.updated-dependencies), ', ') }}"
labels: dependencies,apt
token: ${{ steps.token.outputs.token }}
sign-commits: true

update-vscode-extensions:
name: Update VS Code Extensions (🍨 ${{ matrix.flavor }}, ${{ matrix.file }})
name: ${{ github.event_name == 'pull_request' && '🧪' || '' }} Extensions (🍨 ${{ matrix.flavor }}, ${{ matrix.file }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
flavor: ["cpp", "rust"]
file: ["devcontainer-metadata.json", "devcontainer.json"]
permissions:
contents: write # is needed by peter-evans/create-pull-request to create branches and push commits
pull-requests: write # is needed by peter-evans/create-pull-request to create a PR
steps:
- uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
with:
egress-policy: audit
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: ./.github/actions/update-vscode-extensions
id: update-extensions
with:
input-file: .devcontainer/${{ matrix.flavor }}/${{ matrix.file }}
- name: Generate PR body
run: |
{
echo "> [!NOTE]"
echo "> Before merging this PR, please conduct a manual test checking basic functionality of the updated plug-ins. There are limited automated tests for the VS Code Extension updates."
echo ""
cat "$MARKDOWN_SUMMARY_FILE"
} >> "${RUNNER_TEMP}/pull-request-body.md"
env:
MARKDOWN_SUMMARY_FILE: ${{ steps.update-extensions.outputs.markdown-summary-file }}
- uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
id: token
if: github.event_name != 'pull_request'
with:
app-id: ${{ vars.FOREST_RELEASER_APP_ID }}
private-key: ${{ secrets.FOREST_RELEASER_APP_PRIVATE_KEY }}
- uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
if: github.event_name != 'pull_request'
with:
commit-message: "Update ${{ join(fromJson(steps.update-extensions.outputs.updated-dependencies), ', ') }} in ${{ matrix.file }}"
branch: feature/amp-devcontainer-${{ matrix.flavor }}/update-vscode-extensions-${{ matrix.file }}
body: |
> [!NOTE]
> Before merging this PR, please conduct a manual test checking basic functionality of the updated plug-ins. There are limited automated tests for the VS Code Extension updates.

${{ steps.update-extensions.outputs.markdown-summary }}
body-path: ${{ runner.temp }}/pull-request-body.md
title: "chore(deps, ${{ matrix.flavor }}): update ${{ join(fromJson(steps.update-extensions.outputs.updated-dependencies), ', ') }} in ${{ matrix.file }}"
labels: dependencies,vscode-extensions
token: ${{ steps.token.outputs.token }}
sign-commits: true