Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
jas14 committed Aug 23, 2024
2 parents fd5ba78 + 684a34b commit 9053fcd
Show file tree
Hide file tree
Showing 26 changed files with 1,964 additions and 110 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @heroku/languages
17 changes: 10 additions & 7 deletions .github/workflows/check_changelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@ name: Check Changelog

on:
pull_request:
types: [opened, reopened, edited, synchronize]
types: [opened, reopened, labeled, unlabeled, synchronize]

permissions:
contents: read

jobs:
check-changelog:
runs-on: ubuntu-latest
if: |
!contains(github.event.pull_request.body, '[skip changelog]') &&
!contains(github.event.pull_request.body, '[changelog skip]') &&
!contains(github.event.pull_request.body, '[skip ci]')
if: (!contains(github.event.pull_request.labels.*.name, 'skip changelog'))
steps:
- uses: actions/checkout@v1
- name: Checkout
uses: actions/checkout@v4
- name: Check that CHANGELOG is touched
run: git diff remotes/origin/${{ github.base_ref }} --name-only | grep CHANGELOG.md
run: |
git fetch origin ${{ github.base_ref }} --depth 1 && \
git diff remotes/origin/${{ github.base_ref }} --name-only | grep CHANGELOG.md
35 changes: 35 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: CI

on:
push:
branches: ["main"]
pull_request:

permissions:
contents: read

jobs:
functional-test:
runs-on: ubuntu-22.04
container:
image: heroku/heroku:${{ matrix.stack_number }}-build
options: --user root
strategy:
matrix:
stack_number: ["20", "22", "24"]
env:
STACK: heroku-${{ matrix.stack_number }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Functional tests on heroku:${{ matrix.stack_number }}-build
run: test/run

shell-lint:
runs-on: ubuntu-22.04
container:
image: koalaman/shellcheck-alpine:v0.9.0
steps:
- uses: actions/checkout@v4
- name: shellcheck
run: shellcheck -x bin/compile bin/detect bin/release bin/report
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.anvil
.idea
11 changes: 0 additions & 11 deletions .travis.yml

This file was deleted.

19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,25 @@

## Unreleased

## 2024-06-24

- The cache is now correctly invalidated if the stack version of an existing cache cannot be determined. ([#133](https://github.com/heroku/heroku-buildpack-apt/pull/133))
- When the cache is invalidated, all APT-related files are now removed, rather than only some of them. In particular, this means old APT package index files are cleaned up. ([#133](https://github.com/heroku/heroku-buildpack-apt/pull/133))
- Exclude test/development files from the buildpack archive published to the buildpack registry. ([#135](https://github.com/heroku/heroku-buildpack-apt/pull/135))

## 2024-03-28

- Warn when Aptfile contains no packages ([#126](https://github.com/heroku/heroku-buildpack-apt/pull/126))
- Support sources parts directory for Heroku-24 compatibility ([#119](https://github.com/heroku/heroku-buildpack-apt/pull/119))

## 2024-03-14

- Shell hardening ([#115](https://github.com/heroku/heroku-buildpack-apt/pull/115))
- Handle multi-package lines when capturing buildpack metadata ([#112](https://github.com/heroku/heroku-buildpack-apt/pull/112))

## 2024-03-01

- Add `bin/report` script to capture buildpack metadata ([#110](https://github.com/heroku/heroku-buildpack-apt/pull/110))

## 2021-03-10

Expand Down
19 changes: 19 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
test: heroku-24-build heroku-22-build heroku-20-build

shellcheck:
@shellcheck -x bin/compile bin/detect bin/release bin/report

heroku-24-build:
@echo "Running tests in docker (heroku-24-build)..."
@docker run --user root -v $(shell pwd):/buildpack:ro --rm -it -e "STACK=heroku-24" heroku/heroku:24-build bash -c 'cp -r /buildpack /buildpack_test; cd /buildpack_test/; test/run;'
@echo ""

heroku-22-build:
@echo "Running tests in docker (heroku-22-build)..."
@docker run -v $(shell pwd):/buildpack:ro --rm -it -e "STACK=heroku-22" heroku/heroku:22-build bash -c 'cp -r /buildpack /buildpack_test; cd /buildpack_test/; test/run;'
@echo ""

heroku-20-build:
@echo "Running tests in docker (heroku-20-build)..."
@docker run -v $(shell pwd):/buildpack:ro --rm -it -e "STACK=heroku-20" heroku/heroku:20-build bash -c 'cp -r /buildpack /buildpack_test; cd /buildpack_test/; test/run;'
@echo ""
79 changes: 50 additions & 29 deletions bin/compile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ set -eo pipefail
# parse and derive params
BUILD_DIR=$1
CACHE_DIR=$2
LP_DIR=`cd $(dirname $0); cd ..; pwd`
LP_DIR=$(cd "$(dirname "$0")"; cd ..; pwd)

function error() {
echo " ! $*" >&2
Expand All @@ -29,76 +29,97 @@ function indent() {
esac
}

if ! grep --invert-match -e "^\s*#" -e "^\s*$" -e "^:repo:" -q "${BUILD_DIR}/Aptfile"; then
echo "
! You have no packages listed in your Aptfile. If you don't need custom APT packages,
! delete your Aptfile and remove the buildpack with:
!
! $ heroku buildpacks:remove heroku-community/apt
"
exit 0
fi

# Store which STACK we are running on in the cache to bust the cache if it changes
if [ -f $CACHE_DIR/.apt/STACK ]; then
CACHED_STACK=$(cat "$CACHE_DIR/.apt/STACK")
# This file really should be inside "${CACHE_DIR}/apt" not "${CACHE_DIR}/.apt", however, this
# buildpack has used the wrong directory name for it for some time, so there are many APT-related
# forks that use this path, so for backwards compatibility we're not changing the path, so as to
# not affect apps that have multiple APT-using buildpacks active at the same time.
STACK_VERSION_FILE="${CACHE_DIR}/.apt/STACK"
if [[ -f "${STACK_VERSION_FILE}" ]]; then
CACHED_STACK=$(cat "${STACK_VERSION_FILE}")
else
CACHED_STACK=$STACK
CACHED_STACK=
fi

# Ensure we store the STACK in the cache for next time.
mkdir -p "$CACHE_DIR/.apt"
echo "$STACK" > "$CACHE_DIR/.apt/STACK"
mkdir -p "${CACHE_DIR}/.apt"
echo "${STACK}" > "${STACK_VERSION_FILE}"

APT_CACHE_DIR="$CACHE_DIR/apt/cache"
APT_STATE_DIR="$CACHE_DIR/apt/state"
APT_SOURCELIST_DIR="$CACHE_DIR/apt/sources" # place custom sources.list here
APT_SOURCEPARTS_DIR="$APT_SOURCELIST_DIR/sources.list.d"

APT_SOURCES="$APT_SOURCELIST_DIR/sources.list"

APT_VERSION=$(apt-get -v | awk 'NR == 1{ print $2 }')

case "$APT_VERSION" in
0* | 1.0*) APT_FORCE_YES="--force-yes";;
*) APT_FORCE_YES="--allow-downgrades --allow-remove-essential --allow-change-held-packages";;
0* | 1.0*) APT_FORCE_YES=("--force-yes");;
*) APT_FORCE_YES=("--allow-downgrades" "--allow-remove-essential" "--allow-change-held-packages");;
esac

if [ -f $APT_CACHE_DIR/Aptfile ] && cmp -s $BUILD_DIR/Aptfile $APT_CACHE_DIR/Aptfile && [[ $CACHED_STACK == $STACK ]] ; then
if [[ -f "$APT_CACHE_DIR/Aptfile" ]] && cmp -s "$BUILD_DIR/Aptfile" "$APT_CACHE_DIR/Aptfile" && [[ "$CACHED_STACK" == "$STACK" ]] ; then
# Old Aptfile is the same as new and STACK has not changed
topic "Reusing cache"
else
# Aptfile changed or does not exist or STACK changed
topic "Detected Aptfile or Stack changes, flushing cache"
rm -rf $APT_CACHE_DIR
rm -rf "${CACHE_DIR}/apt"
mkdir -p "$APT_CACHE_DIR/archives/partial"
mkdir -p "$APT_STATE_DIR/lists/partial"
mkdir -p "$APT_SOURCELIST_DIR" # make dir for sources
cp -f "$BUILD_DIR/Aptfile" "$APT_CACHE_DIR/Aptfile"
cat "/etc/apt/sources.list" > "$APT_SOURCES" # no cp here
cp -R "/etc/apt/sources.list.d" "$APT_SOURCEPARTS_DIR"
# add custom repositories from Aptfile to sources.list
# like>> :repo:deb http://cz.archive.ubuntu.com/ubuntu artful main universe
if grep -q -e "^:repo:" $BUILD_DIR/Aptfile; then
if grep -q -e "^:repo:" "$BUILD_DIR/Aptfile"; then
topic "Adding custom repositories"
cat $BUILD_DIR/Aptfile | grep -s -e "^:repo:" | sed 's/^:repo:\(.*\)\s*$/\1/g' >> $APT_SOURCES
grep -s -e "^:repo:" "$BUILD_DIR/Aptfile" | sed 's/^:repo:\(.*\)\s*$/\1/g' >> "$APT_SOURCES"
fi
fi

APT_OPTIONS="-o debug::nolocking=true -o dir::cache=$APT_CACHE_DIR -o dir::state=$APT_STATE_DIR"
APT_OPTIONS=("-o" "debug::nolocking=true" "-o" "dir::cache=$APT_CACHE_DIR" "-o" "dir::state=$APT_STATE_DIR")
# Override the use of /etc/apt/sources.list (sourcelist) and /etc/apt/sources.list.d/* (sourceparts).
APT_OPTIONS="$APT_OPTIONS -o dir::etc::sourcelist=$APT_SOURCES -o dir::etc::sourceparts=/dev/null"
APT_OPTIONS+=("-o" "dir::etc::sourcelist=$APT_SOURCES" "-o" "dir::etc::sourceparts=$APT_SOURCEPARTS_DIR")

topic "Updating apt caches"
apt-get $APT_OPTIONS update | indent
topic "Updating APT package index"
apt-get "${APT_OPTIONS[@]}" update 2>&1 | indent

# BEGIN: installing packages
for PACKAGE in $(cat $BUILD_DIR/Aptfile | grep -v -s -e '^#' | grep -v -s -e "^:repo:" | grep -v -s -e '^blackhole '); do
while IFS= read -r PACKAGE; do
if [[ $PACKAGE == *deb ]]; then
PACKAGE_NAME=$(basename $PACKAGE .deb)
PACKAGE_NAME=$(basename "$PACKAGE" .deb)
PACKAGE_FILE=$APT_CACHE_DIR/archives/$PACKAGE_NAME.deb

topic "Fetching $PACKAGE"
curl --silent --show-error --fail -L -z $PACKAGE_FILE -o $PACKAGE_FILE $PACKAGE 2>&1 | indent
curl --silent --show-error --fail -L -z "$PACKAGE_FILE" -o "$PACKAGE_FILE" "$PACKAGE" 2>&1 | indent
else
topic "Fetching .debs for $PACKAGE"
apt-get $APT_OPTIONS -y $APT_FORCE_YES -d install --reinstall $PACKAGE | indent
# while this is not documented behavior, the Aptfile format technically
# did allow for multiple packages separated by spaces to be specified
# on a single line due to how the download command was implemented so we
# should respect that behavior since users are doing this
IFS=$' \t' read -ra PACKAGE_NAMES <<< "$PACKAGE"
apt-get "${APT_OPTIONS[@]}" -y "${APT_FORCE_YES[@]}" -d install --reinstall "${PACKAGE_NAMES[@]}" | indent
fi
done
done < <(grep --invert-match -e "^\s*#" -e "^\s*$" -e "^:repo:" -e "^blackhole " "${BUILD_DIR}/Aptfile")

mkdir -p $BUILD_DIR/.apt
mkdir -p "$BUILD_DIR/.apt"

for DEB in $(ls -1 $APT_CACHE_DIR/archives/*.deb); do
topic "Installing $(basename $DEB)"
dpkg -x $DEB $BUILD_DIR/.apt/
for DEB in "$APT_CACHE_DIR/archives/"*.deb; do
topic "Installing $(basename "$DEB")"
dpkg -x "$DEB" "$BUILD_DIR/.apt/"
done
# END: installing packages

Expand All @@ -118,8 +139,8 @@ done < <(
# END: blackhole packages

topic "Writing profile script"
mkdir -p $BUILD_DIR/.profile.d
cat <<EOF >$BUILD_DIR/.profile.d/000_apt.sh
mkdir -p "$BUILD_DIR/.profile.d"
cat <<EOF >"$BUILD_DIR/.profile.d/000_apt.sh"
export PATH="\$HOME/.apt/usr/bin:\$PATH"
export LD_LIBRARY_PATH="\$HOME/.apt/usr/lib/x86_64-linux-gnu:\$HOME/.apt/usr/lib/i386-linux-gnu:\$HOME/.apt/usr/lib:\$LD_LIBRARY_PATH"
export LIBRARY_PATH="\$HOME/.apt/usr/lib/x86_64-linux-gnu:\$HOME/.apt/usr/lib/i386-linux-gnu:\$HOME/.apt/usr/lib:\$LIBRARY_PATH"
Expand All @@ -141,4 +162,4 @@ export PKG_CONFIG_PATH="$BUILD_DIR/.apt/usr/lib/x86_64-linux-gnu/pkgconfig:$BUIL
export | grep -E -e ' (PATH|LD_LIBRARY_PATH|LIBRARY_PATH|INCLUDE_PATH|CPATH|CPPPATH|PKG_CONFIG_PATH)=' > "$LP_DIR/export"

topic "Rewrite package-config files"
find $BUILD_DIR/.apt -type f -ipath '*/pkgconfig/*.pc' | xargs --no-run-if-empty -n 1 sed -i -e 's!^prefix=\(.*\)$!prefix='"$BUILD_DIR"'/.apt\1!g'
find "$BUILD_DIR/.apt" -type f -ipath '*/pkgconfig/*.pc' -print0 | xargs -0 --no-run-if-empty -n 1 sed -i -e 's!^prefix=\(.*\)$!prefix='"$BUILD_DIR"'/.apt\1!g'
2 changes: 1 addition & 1 deletion bin/detect
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# bin/detect <build-dir>

if [ -f $1/Aptfile ]; then
if [[ -f "$1/Aptfile" ]]; then
echo "Apt"
exit 0
else
Expand Down
41 changes: 41 additions & 0 deletions bin/report
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
# bin/report <build-dir> <cache-dir> <env-dir>

### Configure environment

set -o errexit # always exit on error
set -o pipefail # don't ignore exit codes when piping output

BUILD_DIR=${1:-}

packages=()
custom_packages=()
custom_repositories=()

while IFS= read -r line; do
if grep --silent -e "^:repo:" <<< "${line}"; then
custom_repositories+=("${line//:repo:/}")
elif [[ $line == *deb ]]; then
custom_packages+=("${line}")
else
IFS=$' \t' read -ra package_names <<< "${line}"
for package_name in "${package_names[@]}"; do
packages+=("${package_name}")
done
fi
done < <(grep --invert-match -e "^\s*#" -e "^\s*$" "${BUILD_DIR}/Aptfile")

output_key_value() {
local key value
key="$1"
shift
# sort & join the array values with a ',' then escape both '\' and '"' characters
value=$(printf '%s\n' "$@" | sort | tr '\n' ',' | sed 's/,$/\n/' | sed 's/\\/\\\\/g' | sed 's/"/\\"/g')
if [[ -n "${value}" ]]; then
echo "$key: \"$value\""
fi
}

output_key_value "packages" "${packages[@]}"
output_key_value "custom_packages" "${custom_packages[@]}"
output_key_value "custom_repositories" "${custom_repositories[@]}"
10 changes: 10 additions & 0 deletions buildpack.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[buildpack]
name = "Apt"

[publish.Ignore]
files = [
".github/",
"test/",
".gitignore",
"Makefile",
]
59 changes: 0 additions & 59 deletions test/compile_test.sh

This file was deleted.

Loading

0 comments on commit 9053fcd

Please sign in to comment.