Skip to content

Commit 4ab8682

Browse files
authored
Merge pull request #32 from assignUser/add-stash-action
Add stash action
2 parents ac08bbe + 944d42f commit 4ab8682

File tree

9 files changed

+732
-0
lines changed

9 files changed

+732
-0
lines changed
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# Copyright (c) The stash contributors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
name: Test Stash Action
15+
16+
on:
17+
pull_request:
18+
push:
19+
branches:
20+
- main
21+
22+
permissions:
23+
contents: read
24+
25+
jobs:
26+
test-deps:
27+
name: "check for dependencies"
28+
runs-on: ubuntu-latest
29+
container: quay.io/centos/centos:stream8
30+
steps:
31+
- uses: actions/checkout@v4
32+
33+
- name: Run action
34+
continue-on-error: true
35+
id: fail
36+
uses: ./stash/restore
37+
with:
38+
path: ./stash
39+
key: this-must-fail
40+
41+
- name: It did not fail
42+
if: ${{ steps.fail.outputs.stash-hit != '' }}
43+
run: |
44+
echo "::error ::Dependency check should have failed!"
45+
exit 1
46+
47+
test-save:
48+
name: "stash/save on ${{ matrix.os }}"
49+
strategy:
50+
fail-fast: false
51+
matrix:
52+
os: [ubuntu-latest, windows-latest, macos-13, macos-14]
53+
runs-on: ${{ matrix.os }}
54+
steps:
55+
- uses: actions/checkout@v4
56+
57+
- name: Run unittests
58+
shell: bash
59+
env:
60+
GH_TOKEN: "${{ github.token }}"
61+
run: |
62+
cd stash/restore
63+
python3 test_get_stash.py
64+
65+
- name: Test Save
66+
uses: ./stash/save
67+
with:
68+
path: stash/
69+
# Create a unique key to test intra workflow artifacts.
70+
key: test/stash-${{ matrix.os }}-${{ github.sha }}
71+
retention-days: '1'
72+
73+
- name: Show rate limit
74+
env:
75+
GH_TOKEN: "${{ github.token }}"
76+
run: gh api -q '.rate' rate_limit
77+
78+
- name: Test Overwrite
79+
id: test
80+
uses: ./stash/save
81+
with:
82+
path: stash/
83+
# Create a unique key to test intra workflow artifacts.
84+
key: test/stash-${{ matrix.os }}-${{ github.sha }}
85+
retention-days: '1'
86+
87+
- name: Show rate limit
88+
env:
89+
GH_TOKEN: "${{ github.token }}"
90+
run: gh api -q '.rate' rate_limit
91+
92+
- name: Check Output
93+
shell: bash
94+
env:
95+
ID: ${{ steps.test.outputs.stash-id }}
96+
URL: ${{ steps.test.outputs.stash-url }}
97+
run: |
98+
if [ -z "$ID" -o -z "$URL" ]; then
99+
echo "Output empty"
100+
exit 1
101+
fi
102+
103+
- name: Check if inter-workflow stash exists
104+
id: stash
105+
uses: ./stash/restore
106+
with:
107+
key: test-stash-cross-${{ matrix.os }}
108+
path: test-stash
109+
110+
- name: Show rate limit
111+
env:
112+
GH_TOKEN: "${{ github.token }}"
113+
run: gh api -q '.rate' rate_limit
114+
115+
- name: Save cross-workflow Stash
116+
if: ${{ steps.stash.outputs.stash-hit == 'false' }}
117+
uses: ./stash/save
118+
with:
119+
path: stash/
120+
key: test-stash-cross-${{ matrix.os }}
121+
retention-days: '90'
122+
123+
test-restore:
124+
name: "stash/restore on ${{ matrix.os }}"
125+
strategy:
126+
fail-fast: false
127+
matrix:
128+
os: [ubuntu-latest, windows-latest, macos-13, macos-14]
129+
needs: test-save
130+
runs-on: ${{ matrix.os }}
131+
steps:
132+
- uses: actions/checkout@v4
133+
134+
- name: Test intra-workflow stash
135+
uses: ./stash/restore
136+
with:
137+
key: test/stash-${{ matrix.os }}-${{ github.sha }}
138+
path: intra/stash/
139+
140+
- shell: bash
141+
run: ls -laR intra
142+
143+
- name: Test inter-workflow stash
144+
uses: ./stash/restore
145+
with:
146+
key: test-stash-cross-${{ matrix.os }}
147+
path: inter/stash/
148+
149+
- shell: bash
150+
run: ls -laR inter/

stash/.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright (c) The stash contributors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
__pycache__

stash/README.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<!--
2+
# Copyright (c) The stash contributors
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
-->
16+
17+
# Stash GitHub Action
18+
19+
`Stash` provides a solution for managing large build caches in your workflows, that doesn't require any secrets and can therefore be used in fork PRs.
20+
It's designed as an alternative to `actions/cache` which struggles with big build caches such as `.ccache` directories due to the repository wide [size limit](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#usage-limits-and-eviction-policy) of 10GB and the fact that caches are [immutable](https://github.com/actions/toolkit/issues/505).
21+
With workflows running multiple configurations across PRs and merge commits this limit is quickly reached, leading to cache evictions, causing CI times to increase.
22+
23+
This action is split into two distinct operations:
24+
- `infrastructure-actions/stash/restore` for fetching a previously stored stash
25+
- `infrastructure-actions/stash/save` for storing a new stash after a build has been completed.
26+
27+
## Features
28+
29+
- Each stash is uploaded as a workflow artifact. In contrasts to `actions/cache` there is no repository wide size limit for artifacts.
30+
- There is no cache eviction, stashes will expire after 5 days by default.
31+
- Artifact storage is free for public repositories and much cheaper than CI minutes (~ 1 Cent/1GB/day) for private repositories.
32+
- No secrets required, stash can be used in fork PRs.
33+
- Follows the same search scope as `actions/cache`: will look for the cache in the current workflow, current branch and finally the base branch of a PR.
34+
This prevents untrusted user caches (e.g. from fork PR CI runs) from being used on the default branch (where actions have elevated permissions by default) or other repo or PR branches.
35+
36+
## Usage
37+
38+
> [!IMPORTANT]
39+
> You have to explicitly save your stash by using `infrastructure-actions/stash/save` action,
40+
> it will not be saved automatically by using `infrastructure-actions/stash/restore`.
41+
42+
To restore a stash before your build process, use the `infrastructure-actions/stash/restore` action in your workflow:
43+
44+
45+
```yaml
46+
steps:
47+
- uses: actions/checkout@v2
48+
- uses: infrastructure-actions/stash/restore@v1
49+
with:
50+
key: 'cache-key'
51+
path: 'path/to/cache'
52+
```
53+
54+
After your build completes, save the stash using the `infrastructure-actions/stash/save` action:
55+
56+
```yaml
57+
steps:
58+
- uses: infrastructure-actions/stash/save@v1
59+
with:
60+
key: 'cache-key'
61+
path: 'path/to/cache'
62+
```
63+
Stashes will expire after 5 days by default.
64+
You can set this from 1-90 days with the `retention-days` input.
65+
Using the `save` action again in the same workflow run will overwrite the existing cache with the same key.
66+
This does apply to each invocation in a matrix job as well!
67+
If you want to keep the old cache, you can use a different key or set `overwrite` to `false`.
68+
69+
### Inputs and Outputs
70+
71+
Each action (restore and save) has specific inputs tailored to its functionality,
72+
they are specifically modeled after `actions/cache` and `actions/upload-artifact` to provide a drop in replacement.
73+
Please refer to the action metadata (`action.yml`) for a comprehensive list of inputs, including descriptions and default values.
74+
75+
Additionally the `restore` action has an output `stash-hit` which is set to `true` if the cache was restored successfully,
76+
`false` if no cache was restored and '' if the action failed (an error will be thrown unless `continue-on-error` is set).
77+
A technical limitation of composite actions like `Stash` is that all outputs are **strings**.
78+
Therefore an explicit comparison has to be used when using the output:
79+
`if: ${{ steps.restore-stash.outputs.stash-hit == 'true' }}`

0 commit comments

Comments
 (0)