Major revisions to everything.

This commit is contained in:
awalsh128 2021-10-10 22:11:39 -07:00
parent 3fa1ba390c
commit 334906ef6e
6 changed files with 294 additions and 88 deletions

View file

@ -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
View 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
View file

@ -1,25 +1,13 @@
BSD 2-Clause License
Copyright 2021 Andrew Walsh
Copyright (c) 2021, Andrew Walsh
All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
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
modification, are permitted provided that the following conditions are met:
http://www.apache.org/licenses/LICENSE-2.0
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
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.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -1 +1,95 @@
# cached-apt-install-action
# cache-apt-pkgs-action
[![License: Apache2](https://shields.io/badge/license-apache2-blue.svg)](https://github.com/awalsh128/fluentcpp/blob/master/LICENSE)
[![GitHub Actions status](https://github.com/awalsh128/cache-apt-pkgs-action/workflows/Tests/badge.svg?branch=main&event=push)](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.

View file

@ -1,20 +1,26 @@
name: 'Cached APT Install'
name: 'Cache APT Packages'
description: 'Install APT based packages and cache them for future runs.'
author: awalsh128
inputs:
cache_key:
description: 'Unique key representing the cache being used.'
required: true
default: ''
packages:
description: 'Space delimited list of packages to install.'
required: true
default: ''
runs:
using: "composite"
steps:
- name: Cache Packages
- name: Create Package Cache
uses: actions/cache@v2
id: cached-apt-install-packages
with:
path: "~/cached-apt-install-packages"
key: cached-apt-install-packages
path: "~/cache-apt-pkgs"
key: cache-apt-pkgs_${{ inputs.cache_key }}
- 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

73
run.sh
View file

@ -3,16 +3,28 @@
cache_dir=$1
packages="${@:2}"
if [ ! -d "$cache_dir" ]; then
echo "Cache directory '$cache_dir' does not exist."
exit 1
fi
if [ $packages = "" ]; then
echo "Packages argument cannot be empty."
exit 2
fi
validate_args() {
echo -n "Validating action arguments... ";
if [ ! -d "$cache_dir" ]; then
echo "aborted.\nCache directory '$cache_dir' does not exist."
return 1
fi
if [ $packages = "" ]; then
echo "aborted.\nPackages argument cannot be empty."
return 2
fi
for package in $packages; do
if apt-cache search ^$package$ | grep $package; then
echo "aborted.\nPackage '$package' not found."
return 3
fi
done
echo "done."
return 0
}
for dir in `ls $cache_dir`; do
clean_cache() {
for dir in `ls $cache_dir`; do
remove=true
for package in $packages; do
if [ $dir == $package ]; then
@ -21,24 +33,28 @@ for dir in `ls $cache_dir`; do
fi
done
[ $remove ] && rm -fr $cache_dir/$dir
done
done
}
for package in $packages; do
restore_pkg() {
package=$1
package_dir=$2
package_dir=$cache_dir/$package
if [ -d $package_dir ]; then
echo "Restoring $package from cache $package_dir..."
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."
}
else
install_and_cache_pkg() {
package=$1
package_dir=$2
echo "Clean install $package and caching to $package_dir..."
echo -n "Clean installing $package... "
sudo apt-get --yes install $package
echo "done."
echo "Caching $package to $package_dir..."
echo -n "Caching $package to $package_dir..."
mkdir --parents $package_dir
# Pipe all package files (no folders) to copy command.
sudo dpkg -L $package |
@ -46,6 +62,23 @@ for package in $packages; do
if test -f $f; then echo $f; fi;
done |
xargs cp -p -t $package_dir
fi
echo "done."
}
validate_code = validate_args
if validate_code -ne 0; then
exit $validate_code
fi
clean_cache
for package in $packages; do
package_dir=$cache_dir/$package
if [ -d $package_dir ]; then
restore_pkg $package $package_dir
else
install_and_cache_pkg $package $package_dir
fi
done
echo "Action complete. ${#packages[@]} packages installed."