Skip to content

Commit 56a9f49

Browse files
committed
Merge branch 'dev' into date-card
2 parents 396176a + 048e754 commit 56a9f49

121 files changed

Lines changed: 3343 additions & 727 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/codeql-analysis.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ jobs:
3232
persist-credentials: false
3333

3434
- name: Initialize CodeQL
35-
uses: github/codeql-action/init@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3
35+
uses: github/codeql-action/init@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4
3636
with:
3737
languages: javascript-typescript
3838
build-mode: none
3939

4040
- name: Perform CodeQL Analysis
41-
uses: github/codeql-action/analyze@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3
41+
uses: github/codeql-action/analyze@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4
4242
with:
4343
category: "/language:javascript-typescript"

.github/workflows/nightly.yaml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,20 @@ jobs:
4242
- name: Bump version
4343
run: script/version_bump.js nightly
4444

45+
# Warm the shared compression cache so releases reuse it (see release.yaml).
46+
- name: Restore compression cache
47+
id: compress-cache
48+
continue-on-error: true
49+
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
50+
with:
51+
path: .compress-cache
52+
key: compress-cache-${{ runner.os }}-${{ github.run_id }}-${{ github.run_attempt }}
53+
restore-keys: |
54+
compress-cache-${{ runner.os }}-
55+
4556
- name: Build nightly Python wheels
57+
env:
58+
COMPRESS_CACHE_DIR: ${{ github.workspace }}/.compress-cache
4659
run: |
4760
pip install build
4861
yarn install
@@ -51,6 +64,16 @@ jobs:
5164
rm -rf dist home_assistant_frontend.egg-info
5265
python3 -m build
5366
67+
# Not gated on the restore step: a transient restore failure (it is
68+
# continue-on-error) must not stop us persisting a freshly built cache.
69+
- name: Save compression cache
70+
if: success()
71+
continue-on-error: true
72+
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
73+
with:
74+
path: .compress-cache
75+
key: compress-cache-${{ runner.os }}-${{ github.run_id }}-${{ github.run_attempt }}
76+
5477
- name: Archive translations
5578
run: tar -czvf translations.tar.gz translations
5679

.github/workflows/release-drafter.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ jobs:
1818
pull-requests: read
1919
runs-on: ubuntu-latest
2020
steps:
21-
- uses: release-drafter/release-drafter@eada3c96a64734dd381cfbda23511034e328ddb0 # v7.6.0
21+
- uses: release-drafter/release-drafter@34d80673e067bdc0c24568d3af899c216adcfaa9 # v7.7.0
2222
env:
2323
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/release.yaml

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
python-version: ${{ env.PYTHON_VERSION }}
3737

3838
- name: Verify version
39-
uses: home-assistant/actions/helpers/verify-version@ab22029681aa532bfe7de5774a9972d67bfbd2c0 # master
39+
uses: home-assistant/actions/helpers/verify-version@a7c616ce81ccda50150bf1595786c71b1883fabb # master
4040

4141
- name: Setup Node and install
4242
uses: ./.github/actions/setup
@@ -48,15 +48,44 @@ jobs:
4848
run: ./script/translations_download
4949
env:
5050
LOKALISE_TOKEN: ${{ secrets.LOKALISE_TOKEN }}
51+
# The app fetches core (backend) translations live from HA, so the
52+
# release build does not need Lokalise's backend project.
53+
SKIP_BACKEND_TRANSLATIONS: "1"
54+
55+
# Restore the content-addressed compression cache. Unchanged chunks and
56+
# static assets are then reused instead of re-run through brotli/zopfli.
57+
- name: Restore compression cache
58+
id: compress-cache
59+
continue-on-error: true
60+
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
61+
with:
62+
path: .compress-cache
63+
key: compress-cache-${{ runner.os }}-${{ github.run_id }}-${{ github.run_attempt }}
64+
restore-keys: |
65+
compress-cache-${{ runner.os }}-
5166
5267
- name: Build and release package
68+
env:
69+
COMPRESS_CACHE_DIR: ${{ github.workspace }}/.compress-cache
5370
run: |
5471
python3 -m pip install build
5572
export SKIP_FETCH_NIGHTLY_TRANSLATIONS=1
5673
script/release
5774
75+
# The build keeps the cache under its size budget, so saving stays bounded.
76+
# A unique key always writes; restore-keys picks the newest on the next
77+
# run. Not gated on the restore step: a transient restore failure (it is
78+
# continue-on-error) must not stop us persisting a freshly built cache.
79+
- name: Save compression cache
80+
if: success()
81+
continue-on-error: true
82+
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
83+
with:
84+
path: .compress-cache
85+
key: compress-cache-${{ runner.os }}-${{ github.run_id }}-${{ github.run_attempt }}
86+
5887
- name: Publish to PyPI
59-
uses: pypa/gh-action-pypi-publish@ba38be9e461d3875417946c167d0b5f3d385a247 # v1.14.1
88+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
6089
with:
6190
skip-existing: true
6291

@@ -125,6 +154,8 @@ jobs:
125154
run: ./script/translations_download
126155
env:
127156
LOKALISE_TOKEN: ${{ secrets.LOKALISE_TOKEN }}
157+
# The landing-page build does not merge backend translations.
158+
SKIP_BACKEND_TRANSLATIONS: "1"
128159
- name: Build landing-page
129160
run: landing-page/script/build_landing_page
130161
- name: Tar folder

.github/workflows/stale.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
runs-on: ubuntu-latest
1616
steps:
1717
- name: 90 days stale policy
18-
uses: actions/stale@1e223db275d687790206a7acac4d1a11bd6fe629 # v10.4.0
18+
uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11.0.0
1919
with:
2020
repo-token: ${{ secrets.GITHUB_TOKEN }}
2121
days-before-stale: 90

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ build/
66
dist/
77
/hass_frontend/
88
/translations/
9+
/.compress-cache/
910
# Composite action source, not build output
1011
!/.github/actions/build/
1112

build-scripts/brotli.mjs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
import { availableParallelism } from "node:os";
1313
import { buffer as readStream } from "node:stream/consumers";
1414
import { promisify } from "node:util";
15-
import { brotliCompress } from "node:zlib";
15+
import { brotliCompress, constants } from "node:zlib";
16+
import { withCache } from "./compress-cache.mjs";
1617
import { ParallelTransform } from "./parallel-transform.mjs";
1718

1819
const EXTENSION = ".br";
@@ -24,23 +25,32 @@ const compress = promisify(brotliCompress);
2425
* @param {boolean} [options.skipLarger] Drop files that compression grows.
2526
* @param {object} [options.params] Brotli parameters, passed to zlib as-is.
2627
*/
27-
export default ({ skipLarger = false, params } = {}) =>
28-
new ParallelTransform(availableParallelism(), async (file) => {
28+
export default ({ skipLarger = false, params } = {}) => {
29+
// Isolate cache entries by anything that changes the output bytes: the brotli
30+
// quality, and the node major that produced them.
31+
const quality = params?.[constants.BROTLI_PARAM_QUALITY] ?? "default";
32+
const namespace = `brotli-q${quality}-node${process.versions.node.split(".")[0]}`;
33+
34+
return new ParallelTransform(availableParallelism(), async (file) => {
2935
if (file.isNull()) {
3036
return file;
3137
}
3238
if (file.isStream()) {
3339
file.contents = await readStream(file.contents);
3440
}
3541

36-
const compressed = await compress(file.contents, { params });
37-
if (skipLarger && compressed.length >= file.contents.length) {
42+
const compressed = await withCache(namespace, file.contents, async () => {
43+
const out = await compress(file.contents, { params });
3844
// Dropped rather than passed through, as gulp-brotli did: the
3945
// uncompressed file is already in the output directory.
46+
return skipLarger && out.length >= file.contents.length ? undefined : out;
47+
});
48+
if (compressed === undefined) {
4049
return undefined;
4150
}
4251

4352
file.contents = compressed;
4453
file.path += EXTENSION;
4554
return file;
4655
});
56+
};

0 commit comments

Comments
 (0)