Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
500505c
Add test
sergv Jun 18, 2025
2317a67
Rearrange genPureArgs for hsc2hs without changing semantics
sergv Jun 19, 2025
c917edc
Deduplicate arguments that hsc2hs passes to gcc and ld
sergv Jun 19, 2025
e38f45d
Add changelog
sergv Jun 19, 2025
c3b3b82
Override C compiler for testing that no duplicate arguments are passed
sergv Jun 19, 2025
20460e9
Fix typo exsting
philderbeast Jul 16, 2025
cfbe545
Merge pull request #11005 from sergv/deduplicate-hsc2hs-args
mergify[bot] Jul 17, 2025
6205b02
Merge pull request #11076 from cabalism/typo/exsting
mergify[bot] Jul 19, 2025
a6e4162
Bump counts with hlint-3.8
philderbeast Jul 18, 2025
46099cf
Typo, seach, in comment
philderbeast Jul 20, 2025
e55b866
Bump to hlint-3.10
philderbeast Jul 18, 2025
9a67ecc
Merge pull request #11081 from cabalism/typo/seach
mergify[bot] Jul 22, 2025
7daa882
Merge pull request #11082 from cabalism/bump/hlint-3.10
mergify[bot] Jul 22, 2025
8c46f48
CI: add GHC 8.6.5 to validate-old-ghcs
ulysses4ever Jul 15, 2025
6d6fc4c
Merge pull request #11074 from haskell/ulysses4ever-patch-3
mergify[bot] Jul 22, 2025
96f1ff6
Migrate release CI back to github
hasufell Nov 13, 2023
77451e3
Skip T5634 on Alpine
hasufell Jul 7, 2025
2cc8a0b
Disable 32bit test
hasufell Jul 18, 2025
96cd816
Add FreeBSD releases
hasufell Jul 18, 2025
74386aa
Downstreamify
hasufell Jul 22, 2025
9dcc0ea
Do nightly release
hasufell Jul 15, 2025
5e72db5
Only build 2 flavors of linux binaries
hasufell Jul 21, 2025
0a74ea1
Add rebase CI
hasufell Jul 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/actions/download/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: 'Download artifact'
description: 'Download artifacts with normalized names'
inputs:
name:
required: true
type: string
path:
required: true
type: string

runs:
using: "composite"
steps:
- name: Normalise name
run: |
name=${{ inputs.name }}
echo "NAME=${name//\//_}" >> "$GITHUB_ENV"
shell: bash

- name: Download artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.NAME }}
path: ${{ inputs.path }}

33 changes: 33 additions & 0 deletions .github/actions/upload/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: 'Upload artifact'
description: 'Upload artifacts with normalized names'
inputs:
if-no-files-found:
default: 'error'
type: string
name:
required: true
type: string
path:
required: true
type: string
retention-days:
default: 0
type: number

runs:
using: "composite"
steps:
- name: Normalise name
run: |
name=${{ inputs.name }}
echo "NAME=${name//\//_}" >> "$GITHUB_ENV"
shell: bash

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
if-no-files-found: ${{ inputs.if-no-files-found }}
retention-days: ${{ inputs.retention-days }}
name: ${{ env.NAME }}
path: ${{ inputs.path }}

55 changes: 55 additions & 0 deletions .github/scripts/build.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
set -eux

uname -a
uname -p
uname
pwd
env

if [ "${RUNNER_OS}" = Windows ] ; then
ext=".exe"
else
ext=""
fi

ghcup --no-verbose install ghc --set --install-targets "${GHC_TARGETS}" "${GHC_VERSION}"

cabal update
cabal user-config diff
cabal user-config init -f
"ghc-${GHC_VERSION}" --info
"ghc" --info

# shellcheck disable=SC2206
args=(
-w "ghc-$GHC_VERSION"
--disable-profiling
--enable-executable-stripping
--project-file=cabal.release.project
${ADD_CABAL_ARGS}
)

cabal v2-build "${args[@]}" cabal-install

mkdir -p "out"
# shellcheck disable=SC2154
cp "$(cabal list-bin "${args[@]}" cabal-install:exe:cabal)" "out/cabal$ext"
cp dist-newstyle/cache/plan.json "out/plan.json"
cd "out/"

# create tarball/zip
TARBALL_PREFIX="cabal-install-$("./cabal" --numeric-version)"
case "${TARBALL_EXT}" in
zip)
zip "${TARBALL_PREFIX}-${ARTIFACT}.${TARBALL_EXT}" "cabal${ext}" plan.json
;;
tar.xz)
tar caf "${TARBALL_PREFIX}-${ARTIFACT}.${TARBALL_EXT}" "cabal${ext}" plan.json
;;
*)
fail "Unknown TARBALL_EXT: ${TARBALL_EXT}"
;;
esac

rm "cabal${ext}" plan.json

58 changes: 58 additions & 0 deletions .github/scripts/rebase_local.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/bin/bash

set -eux

upstream_repo=$1
# of the form [<branch>:<rebase-target>], e.g.:
# BA:master B1:master B2:B1 B3:B2
spec=$2

{

git remote add upstream "${upstream_repo}" || true
git fetch upstream

output_branches=()

# sync master with upstream
git checkout master
git reset --hard upstream/master
output_branches+=( "master" )

# rebase each branch
mkdir -p rebase
for branch_spec in ${spec} ; do
branch=$(echo "${branch_spec}" | awk -F ':' '{ print $1 }')
rebase_target=$(echo "${branch_spec}" | awk -F ':' '{ print $2 }')
git checkout "${branch}"
common_ancestor=$(git merge-base "${branch}" "origin/${rebase_target}")
[ -e rebase/"${branch}" ] && exit 1
mkdir -p rebase/"${branch}"
(
cd rebase/"${branch}"
echo "${common_ancestor}" > BASE_COMMIT
git format-patch "${common_ancestor}".."${branch}"
)
if compgen -G rebase/"${branch}"/*.patch > /dev/null; then
git reset --hard "${rebase_target}"
git am --3way rebase/"${branch}"/*.patch
fi
output_branches+=( "${branch}" )
done
unset branch_spec branch

# cherry-pick on stable-master
git checkout stable-master
git reset --hard upstream/master
for branch_spec in ${spec} ; do
branch=$(echo "${branch_spec}" | awk -F ':' '{ print $1 }')
if compgen -G "rebase/${branch}"/*.patch > /dev/null; then
git am --3way "rebase/${branch}"/*.patch
fi
done
output_branches+=( "stable-master" )

} >&2

echo "${output_branches[*]}"

167 changes: 167 additions & 0 deletions .github/scripts/rebase_spec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
#!/bin/bash

# Branch regex we consider for rebase targets.
# For our purposes this is usually 'stable-haskell/feature/*'.
# 'master' is always considered.
branch_regex=$1
shift 1
declare -a input_branches
input_branches=( "$@" )
set -eux

[ ${#input_branches[@]} -eq 0 ] &&
input_branches=( $(gh pr list --label rebase --state open --json headRefName --jq ".[] | select( .headRefName | match(\"${branch_regex}\")) | .headRefName" --template '{{range .}}{{tablerow .headRefName}}{{end}}') )

branch_list=( )
declare -A branch_map

# @FUNCTION: die
# @USAGE: [msg]
# @DESCRIPTION:
# Exits the shell script with status code 2
# and prints the given message in red to STDERR, if any.
die() {
(>&2 red_message "$1")
exit 2
}

# @FUNCTION: red_message
# @USAGE: <msg>
# @DESCRIPTION:
# Print a red message.
red_message() {
printf "\\033[0;31m%s\\033[0m\\n" "$1"
}

# @FUNCTION: array_contains
# @USAGE: <arr_ref> <val>
# @DESCRIPTION:
# Checks whether the array reference contains the given value.
# @RETURN: 0 if value exists, 1 otherwise
array_contains() {
local -n arr=$1
local val=$2
shift 2
if [[ " ${arr[*]} " =~ [[:space:]]${val}[[:space:]] ]]; then
return 0
else
return 1
fi
}

max_backtrack=10

# @FUNCTION: backtrack
# @USAGE: <map_ref> <start_key> <abort_value>
# @DESCRIPTION:
# Backtrack dependencies through an array list.
# E.g. given an associated array with key value pairs of:
# B1 -> M
# B2 -> B1
# B3 -> B2
#
# ...if we pass B3 as start_key and M as abort_value, then
# we receive the flattened ordered list "B1 B2 B3"
# @STDOUT: space separated list of backtracked values
backtrack() {
backtrack_ 0 "$1" "$2" "$3"
}

# internal to track backtrack depth
backtrack_() {
local depth=$1
if [[ $depth -gt $max_backtrack ]] ; then
die "Dependency backtracking too deep... aborting!"
fi
shift 1

if [[ $1 != map ]] ; then
local -n map=$1
fi

local base=$2
local abort_value=$3
local value

if [ "${base}" = "${abort_value}" ] ; then
return
fi

value=${map[$base]}

if [ "${value}" = "${abort_value}" ] ; then
if ! array_contains branch_list "${base}" ; then
echo "${base}"
fi
else
if array_contains branch_list "${base}" ; then
backtrack_ $((depth++)) map "${map[$value]}" "${abort_value}"
else
echo "$(backtrack_ $((depth++)) map "${map[$base]}" "${abort_value}")" "${base}"
fi
fi
}

create_branch_map() {
local -n arr=$1
local -n discovered=$2
local -n map=$3

while IFS= read -r branch || [[ -n $branch ]]; do
rebase_target=$(git branch --merged "${branch}" --sort="ahead-behind:${branch}" --format="%(refname:short)" | grep -e "${branch_regex}" -e '^master$' | awk 'NR==2{print;exit}')

# this is the case when the branch is actually behind master... we then
# still want to rebase against master
if [ -z "${rebase_target}" ] ; then
rebase_target=master
fi

if ! array_contains input_branches "${rebase_target}" && [ "${rebase_target}" != "master" ] ; then
discovered+=( "${rebase_target}" )
fi

map["${branch}"]="${rebase_target}"
done < <(printf '%s\n' "${arr[@]}")
}

{

# create branch rebase tree
# we're doing that on the state of the local tree/master
newly_detected_input_branches=( )
create_branch_map input_branches newly_detected_input_branches branch_map
# these shenanigns are needed in case the rebase target branches themselves do not have
# the 'rebase' label... this would break cherry-picking on master, so we include "parent"
# branches regardless
while true ; do
if [ ${#newly_detected_input_branches[@]} -eq 0 ] ; then
break
else
nothing=( )
create_branch_map newly_detected_input_branches nothing branch_map
newly_detected_input_branches=( "${nothing[@]}" )
fi
done

} >&2

# flatten recursively
for key in "${!branch_map[@]}"; do
value=${branch_map[$key]}
if [ "${value}" = "master" ] ; then
if ! array_contains branch_list "${key}" ; then
branch_list+=( "${key}" )
fi
else
# shellcheck disable=SC2207
branch_list+=( $(backtrack branch_map "$key" "master") )
fi
done
unset key

result=( )
for key in "${branch_list[@]}"; do
result+=( "${key}:${branch_map[$key]}" )
done
echo "${result[@]}"

34 changes: 34 additions & 0 deletions .github/scripts/test.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
set -eux

env
pwd
ls -lah

cd out
case "${TARBALL_EXT}" in
zip)
unzip ./cabal-install-*-"${ARTIFACT}.${TARBALL_EXT}"
;;
tar.xz)
tar xf ./cabal-install-*-"${ARTIFACT}.${TARBALL_EXT}"
;;
*)
fail "Unknown TARBALL_EXT: ${TARBALL_EXT}"
;;
esac
cd ..

ghcup --no-verbose install ghc --set --install-targets "${GHC_TEST_TARGETS}" "${GHC_TEST_VERSION}"

cabal update

# TODO: we want to avoid building here... we should just
# be using the previously built 'cabal-tests' binary
# Also see https://github.com/haskell/cabal/issues/11048
cabal run -w "ghc-${GHC_TEST_VERSION}" ${ADD_CABAL_ARGS} cabal-testsuite:cabal-tests -- \
--with-cabal "$(pwd)/out/cabal" \
--intree-cabal-lib "$(pwd)" \
--test-tmp "$(pwd)/testdb" \
--skip-setup-tests \
-j "$(nproc || sysctl -n hw.ncpu || getconf _NPROCESSORS_ONLN || echo 1)"

2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
- uses: actions/checkout@v4
- uses: haskell-actions/hlint-setup@v2
with:
version: "3.8"
version: "3.10"
- uses: haskell-actions/hlint-run@v2
with:
path: "."
Expand Down
Loading
Loading