mirror of
https://github.com/awalsh128/cache-apt-pkgs-action.git
synced 2025-09-20 10:07:08 +00:00
Major revisions to everything.
This commit is contained in:
parent
3fa1ba390c
commit
334906ef6e
22
.github/workflows/main.yml
vendored
22
.github/workflows/main.yml
vendored
|
@ -1,22 +0,0 @@
|
||||||
on: [push]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
install_packages:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Test job to install and cache APT packages (i.e. rolldice, dot).
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: actions/cached-apt-install-action@v1
|
|
||||||
with:
|
|
||||||
packages: rolldice dot
|
|
||||||
test_packages_cache:
|
|
||||||
needs: install_packages
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Test job to verify cached APT packages (i.e. rolldice, dot).
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- run: |
|
|
||||||
[ -d "~/cached-apt-install-packages" ] || exit 1;
|
|
||||||
[ -d "~/cached-apt-install-packages/rolldice" ] || exit 2;
|
|
||||||
[ -d "~/cached-apt-install-packages/dot" ] || exit 3;
|
|
||||||
- shell: bash
|
|
107
.github/workflows/tests.yml
vendored
Normal file
107
.github/workflows/tests.yml
vendored
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
name: Success Tests
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
install:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Install and cache.
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/cached-apt-install-action@v1
|
||||||
|
with:
|
||||||
|
cache_key: ${{ env.GITHUB_JOB }}
|
||||||
|
packages: dot rolldice
|
||||||
|
|
||||||
|
verify:
|
||||||
|
needs: install
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Verify cached installs.
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- run: |
|
||||||
|
[ -d "~/cached-apt-install-packages" ] || exit 1;
|
||||||
|
[ -d "~/cached-apt-install-packages/dot" ] || exit 2;
|
||||||
|
[ -d "~/cached-apt-install-packages/rolldice" ] || exit 3;
|
||||||
|
|
||||||
|
add_install:
|
||||||
|
needs: verify
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Add another install and cache.
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/cached-apt-install-action@v1
|
||||||
|
with:
|
||||||
|
cache_key: ${{ env.GITHUB_JOB }}
|
||||||
|
packages: dot rolldice g++
|
||||||
|
|
||||||
|
verify_add:
|
||||||
|
needs: add_install
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Verify added and cached install.
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- run: |
|
||||||
|
[ -d "~/cached-apt-install-packages" ] || exit 4;
|
||||||
|
[ -d "~/cached-apt-install-packages/dot" ] || exit 5;
|
||||||
|
[ -d "~/cached-apt-install-packages/g++" ] || exit 6;
|
||||||
|
[ -d "~/cached-apt-install-packages/rolldice" ] || exit 7;
|
||||||
|
|
||||||
|
verify_cleanup:
|
||||||
|
needs: verify_add
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Verify omitted packages are cleaned up.
|
||||||
|
steps:
|
||||||
|
- uses: actions/cached-apt-install-action@v1
|
||||||
|
with:
|
||||||
|
cache_key: ${{ env.GITHUB_JOB }}_1
|
||||||
|
packages: dot g++
|
||||||
|
- run: |
|
||||||
|
[ -d "~/cached-apt-install-packages" ] || exit 8;
|
||||||
|
[ -d "~/cached-apt-install-packages/dot" ] || exit 9;
|
||||||
|
[ -d "~/cached-apt-install-packages/g++" ] || exit 10;
|
||||||
|
[ -d "~/cached-apt-install-packages/rolldice" ] && exit 11;
|
||||||
|
|
||||||
|
verify_isolation:
|
||||||
|
needs: verify_add
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Verify cache state is not shared.
|
||||||
|
steps:
|
||||||
|
- uses: actions/cached-apt-install-action@v1
|
||||||
|
with:
|
||||||
|
cache_key: ${{ env.GITHUB_JOB }}_1
|
||||||
|
packages: show-motd
|
||||||
|
- run: |
|
||||||
|
[ -d "~/cached-apt-install-packages" ] || exit 12;
|
||||||
|
[ -d "~/cached-apt-install-packages/motd" ] || exit 13;
|
||||||
|
[ -d "~/cached-apt-install-packages/dot" ] && exit 14;
|
||||||
|
[ -d "~/cached-apt-install-packages/g++" ] && exit 15;
|
||||||
|
[ -d "~/cached-apt-install-packages/rolldice" ] && exit 16;
|
||||||
|
|
||||||
|
no_packages:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: No packages passed.
|
||||||
|
steps:
|
||||||
|
- name: Execute
|
||||||
|
uses: actions/cached-apt-install-action@v1
|
||||||
|
with:
|
||||||
|
cache_key:
|
||||||
|
packages: dot
|
||||||
|
continue-on-error: true
|
||||||
|
- name: Verify
|
||||||
|
if: steps.execute.outcom != 'failure'
|
||||||
|
run: exit 1
|
||||||
|
|
||||||
|
package_not_found:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Package not found.
|
||||||
|
steps:
|
||||||
|
- name: Execute
|
||||||
|
uses: actions/cached-apt-install-action@v1
|
||||||
|
with:
|
||||||
|
cache_key: ${{ env.GITHUB_JOB }}
|
||||||
|
packages: package_that_doesnt_exist
|
||||||
|
continue-on-error: true
|
||||||
|
- name: Verify
|
||||||
|
if: steps.execute.outcome != 'failure'
|
||||||
|
run: exit 1
|
32
LICENSE
32
LICENSE
|
@ -1,25 +1,13 @@
|
||||||
BSD 2-Clause License
|
Copyright 2021 Andrew Walsh
|
||||||
|
|
||||||
Copyright (c) 2021, Andrew Walsh
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
All rights reserved.
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this
|
Unless required by applicable law or agreed to in writing, software
|
||||||
list of conditions and the following disclaimer.
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
See the License for the specific language governing permissions and
|
||||||
this list of conditions and the following disclaimer in the documentation
|
limitations under the License.
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
||||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
96
README.md
96
README.md
|
@ -1 +1,95 @@
|
||||||
# cached-apt-install-action
|
# cache-apt-pkgs-action
|
||||||
|
|
||||||
|
[](https://github.com/awalsh128/fluentcpp/blob/master/LICENSE)
|
||||||
|
[](https://github.com/awalsh128/cache-apt-pkgs-action/actions?query=workflow%3ATests)
|
||||||
|
|
||||||
|
This action allows caching of Advanced Package Tool (APT) package dependencies to improve workflow execution time.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
This action is a composition of [actions/cache](https://github.com/actions/cache/README.md) and the `apt` utility. Some actions require additional APT based packages to be installed in order for other steps to be executed. Packages can be installed when ran but can consume much of the execution workflow time.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Pre-requisites
|
||||||
|
|
||||||
|
Create a workflow `.yml` file in your repositories `.github/workflows` directory. An [example workflow](#example-workflow) is available below. For more information, reference the GitHub Help Documentation for [Creating a workflow file](https://help.github.com/en/articles/configuring-a-workflow#creating-a-workflow-file).
|
||||||
|
|
||||||
|
### Inputs
|
||||||
|
|
||||||
|
* `key` - Unique key representing the cache being used.
|
||||||
|
* `packages` - Space delimited list of packages to install.
|
||||||
|
|
||||||
|
### Cache scopes
|
||||||
|
|
||||||
|
The cache is scoped to the key and branch. The default branch cache is available to other branches.
|
||||||
|
|
||||||
|
See [Matching a cache key](https://help.github.com/en/actions/configuring-and-managing-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key) for more info.
|
||||||
|
|
||||||
|
### Example workflow
|
||||||
|
|
||||||
|
This was a motivating use case for creating this action.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: Documentation
|
||||||
|
|
||||||
|
on: push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
build_and_deploy_docs:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Build Doxygen documentation and deploy
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: awalsh128/cache-apt-pkgs-action-action@v1
|
||||||
|
with:
|
||||||
|
cache_key: doxygen_env
|
||||||
|
packages: dia doxygen doxygen-doc doxygen-gui doxygen-latex graphviz mscgen
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
|
||||||
|
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||||
|
|
||||||
|
- name: Deploy
|
||||||
|
uses: JamesIves/github-pages-deploy-action@4.1.5
|
||||||
|
with:
|
||||||
|
branch: gh-pages
|
||||||
|
folder: ${{github.workspace}}/build/website
|
||||||
|
```
|
||||||
|
|
||||||
|
## Creating a cache key
|
||||||
|
|
||||||
|
A cache key can include any of the contexts, functions, literals, and operators supported by GitHub Actions.
|
||||||
|
|
||||||
|
For example, using the [`hashFiles`](https://help.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#hashfiles) function allows you to create a new cache when dependencies change.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- uses: awalsh128/cache-apt-pkgs-action@v1
|
||||||
|
with:
|
||||||
|
cache_key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
|
||||||
|
packages: dot
|
||||||
|
```
|
||||||
|
|
||||||
|
Additionally, you can use arbitrary command output in a cache key, such as a date or software version:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# http://man7.org/linux/man-pages/man1/date.1.html
|
||||||
|
- name: Get Epoch Seconds
|
||||||
|
id: get-epoch-sec
|
||||||
|
run: |
|
||||||
|
echo "::set-output name=epoch_sec::$(/bin/date +%s)"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- uses: awalsh128/cache-apt-pkgs-action@v1
|
||||||
|
with:
|
||||||
|
cache_key: ${{ runner.os }}-${{ steps.get-epoch-sec.outputs.epoch_sec }}-${{ hashFiles('**/lockfiles') }}
|
||||||
|
packages: dot
|
||||||
|
```
|
||||||
|
|
||||||
|
See [Using contexts to create cache keys](https://help.github.com/en/actions/configuring-and-managing-workflows/caching-dependencies-to-speed-up-workflows#using-contexts-to-create-cache-keys)
|
||||||
|
|
||||||
|
## Cache Limits
|
||||||
|
|
||||||
|
A repository can have up to 5GB of caches. Once the 5GB limit is reached, older caches will be evicted based on when the cache was last accessed. Caches that are not accessed within the last week will also be evicted.
|
||||||
|
|
20
action.yml
20
action.yml
|
@ -1,20 +1,26 @@
|
||||||
name: 'Cached APT Install'
|
name: 'Cache APT Packages'
|
||||||
description: 'Install APT based packages and cache them for future runs.'
|
description: 'Install APT based packages and cache them for future runs.'
|
||||||
|
author: awalsh128
|
||||||
|
|
||||||
inputs:
|
inputs:
|
||||||
|
cache_key:
|
||||||
|
description: 'Unique key representing the cache being used.'
|
||||||
|
required: true
|
||||||
|
default: ''
|
||||||
packages:
|
packages:
|
||||||
description: 'Space delimited list of packages to install.'
|
description: 'Space delimited list of packages to install.'
|
||||||
required: true
|
required: true
|
||||||
default: ''
|
default: ''
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
steps:
|
steps:
|
||||||
- name: Cache Packages
|
- name: Create Package Cache
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
id: cached-apt-install-packages
|
with:
|
||||||
with:
|
path: "~/cache-apt-pkgs"
|
||||||
path: "~/cached-apt-install-packages"
|
key: cache-apt-pkgs_${{ inputs.cache_key }}
|
||||||
key: cached-apt-install-packages
|
|
||||||
|
|
||||||
- name: Install Packages
|
- name: Install Packages
|
||||||
run: ${{ github.action_path }}/install.sh "~/cached-apt-install-packages" "${{ inputs.packages }}"
|
run: ${{ github.action_path }}/run.sh "~/cache-apt-pkgs" "${{ inputs.packages }}"
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
105
run.sh
105
run.sh
|
@ -3,49 +3,82 @@
|
||||||
cache_dir=$1
|
cache_dir=$1
|
||||||
packages="${@:2}"
|
packages="${@:2}"
|
||||||
|
|
||||||
if [ ! -d "$cache_dir" ]; then
|
validate_args() {
|
||||||
echo "Cache directory '$cache_dir' does not exist."
|
echo -n "Validating action arguments... ";
|
||||||
exit 1
|
if [ ! -d "$cache_dir" ]; then
|
||||||
fi
|
echo "aborted.\nCache directory '$cache_dir' does not exist."
|
||||||
if [ $packages = "" ]; then
|
return 1
|
||||||
echo "Packages argument cannot be empty."
|
fi
|
||||||
exit 2
|
if [ $packages = "" ]; then
|
||||||
fi
|
echo "aborted.\nPackages argument cannot be empty."
|
||||||
|
return 2
|
||||||
for dir in `ls $cache_dir`; do
|
fi
|
||||||
remove=true
|
|
||||||
for package in $packages; do
|
for package in $packages; do
|
||||||
if [ $dir == $package ]; then
|
if apt-cache search ^$package$ | grep $package; then
|
||||||
remove=false
|
echo "aborted.\nPackage '$package' not found."
|
||||||
break
|
return 3
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
[ $remove ] && rm -fr $cache_dir/$dir
|
echo "done."
|
||||||
done
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
clean_cache() {
|
||||||
|
for dir in `ls $cache_dir`; do
|
||||||
|
remove=true
|
||||||
|
for package in $packages; do
|
||||||
|
if [ $dir == $package ]; then
|
||||||
|
remove=false
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
[ $remove ] && rm -fr $cache_dir/$dir
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_pkg() {
|
||||||
|
package=$1
|
||||||
|
package_dir=$2
|
||||||
|
|
||||||
|
echo -n "Restoring $package from cache $package_dir... "
|
||||||
|
sudo cp --verbose --force --recursive $package_dir/* /
|
||||||
|
sudo apt-get --yes --only-upgrade install $package
|
||||||
|
echo "done."
|
||||||
|
}
|
||||||
|
|
||||||
|
install_and_cache_pkg() {
|
||||||
|
package=$1
|
||||||
|
package_dir=$2
|
||||||
|
|
||||||
|
echo -n "Clean installing $package... "
|
||||||
|
sudo apt-get --yes install $package
|
||||||
|
echo "done."
|
||||||
|
|
||||||
|
echo -n "Caching $package to $package_dir..."
|
||||||
|
mkdir --parents $package_dir
|
||||||
|
# Pipe all package files (no folders) to copy command.
|
||||||
|
sudo dpkg -L $package |
|
||||||
|
while IFS= read -r f; do
|
||||||
|
if test -f $f; then echo $f; fi;
|
||||||
|
done |
|
||||||
|
xargs cp -p -t $package_dir
|
||||||
|
echo "done."
|
||||||
|
}
|
||||||
|
|
||||||
|
validate_code = validate_args
|
||||||
|
if validate_code -ne 0; then
|
||||||
|
exit $validate_code
|
||||||
|
fi
|
||||||
|
|
||||||
|
clean_cache
|
||||||
|
|
||||||
for package in $packages; do
|
for package in $packages; do
|
||||||
|
|
||||||
package_dir=$cache_dir/$package
|
package_dir=$cache_dir/$package
|
||||||
|
|
||||||
if [ -d $package_dir ]; then
|
if [ -d $package_dir ]; then
|
||||||
|
restore_pkg $package $package_dir
|
||||||
echo "Restoring $package from cache $package_dir..."
|
|
||||||
sudo cp --verbose --force --recursive $package_dir/* /
|
|
||||||
sudo apt-get --yes --only-upgrade install $package
|
|
||||||
|
|
||||||
else
|
else
|
||||||
|
install_and_cache_pkg $package $package_dir
|
||||||
echo "Clean install $package and caching to $package_dir..."
|
|
||||||
sudo apt-get --yes install $package
|
|
||||||
|
|
||||||
echo "Caching $package to $package_dir..."
|
|
||||||
mkdir --parents $package_dir
|
|
||||||
# Pipe all package files (no folders) to copy command.
|
|
||||||
sudo dpkg -L $package |
|
|
||||||
while IFS= read -r f; do
|
|
||||||
if test -f $f; then echo $f; fi;
|
|
||||||
done |
|
|
||||||
xargs cp -p -t $package_dir
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
done
|
done
|
||||||
|
|
||||||
|
echo "Action complete. ${#packages[@]} packages installed."
|
||||||
|
|
Loading…
Reference in a new issue