diff --git a/.gitea/workflows/source-release.yml b/.gitea/workflows/source-release.yml new file mode 100644 index 0000000..3e8e4e2 --- /dev/null +++ b/.gitea/workflows/source-release.yml @@ -0,0 +1,290 @@ +name: Source release + +on: + push: + tags: + - "v*" + branches: + - master + workflow_dispatch: + +jobs: + source-package: + runs-on: ubuntu-latest + + env: + GITEA_API: https://gitea.disconnected-by-peer.at/api/v1 + OWNER: mars_nwe + REPO: ipx-utils + + steps: + - name: Check out source + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + token: ${{ secrets.RELEASE_TOKEN }} + + - name: Fetch tags explicitly + run: | + set -e + git fetch --force --tags + echo "describe:" + git describe --tags --long --match 'v*' --always || true + echo "exact tag:" + git describe --tags --exact-match || true + echo "points-at-head:" + git tag --points-at HEAD || true + + - name: Install build dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + build-essential \ + autoconf \ + automake \ + autopoint \ + gettext \ + gettext-base \ + pkg-config \ + curl \ + jq + + - name: Determine version + id: version + env: + REF_TYPE: ${{ gitea.ref_type || github.ref_type }} + REF_NAME: ${{ gitea.ref_name || github.ref_name }} + SHA: ${{ gitea.sha || github.sha }} + run: | + set -e + + BASE_VERSION="$(sed -n 's/^AC_INIT(\[\([^]]*\)\], *\[\([^]]*\)\].*/\2/p' configure.ac | head -n1)" + PACKAGE_NAME="$(sed -n 's/^AC_INIT(\[\([^]]*\)\], *\[\([^]]*\)\].*/\1/p' configure.ac | head -n1)" + + if [ -z "$BASE_VERSION" ] || [ -z "$PACKAGE_NAME" ]; then + echo "Could not determine package/version from configure.ac" + exit 1 + fi + + if [ "$REF_TYPE" = "tag" ]; then + VERSION="$BASE_VERSION" + DIST_BASENAME="${PACKAGE_NAME}-${VERSION}" + else + DESCRIBE="$(git describe --tags --long --match 'v*' --always)" + COUNT="$(printf '%s' "$DESCRIBE" | sed -nE 's/^v?[0-9][^-]*-([0-9]+)-g[0-9a-f]+$/\1/p')" + GITID="$(printf '%s' "$DESCRIBE" | sed -nE 's/^v?[0-9][^-]*-[0-9]+-(g[0-9a-f]+)$/\1/p')" + + if [ -z "$COUNT" ] || [ -z "$GITID" ]; then + COUNT="$(git rev-list --count HEAD)" + GITID="g$(printf '%s' "$SHA" | cut -c1-7)" + fi + + VERSION="${BASE_VERSION}-dev.${COUNT}-${GITID}" + DIST_BASENAME="${PACKAGE_NAME}-${VERSION}" + fi + + echo "package_name=$PACKAGE_NAME" >> "$GITHUB_OUTPUT" + echo "base_version=$BASE_VERSION" >> "$GITHUB_OUTPUT" + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + echo "dist_basename=$DIST_BASENAME" >> "$GITHUB_OUTPUT" + + echo "Package: $PACKAGE_NAME" + echo "Base version: $BASE_VERSION" + echo "Release version: $VERSION" + echo "Dist basename: $DIST_BASENAME" + + - name: Set development version + if: ${{ (gitea.ref_type || github.ref_type) != 'tag' }} + env: + VERSION: ${{ steps.version.outputs.version }} + run: | + set -e + sed -i -E "s/^AC_INIT\(\[ipx-utils\], *\[[^]]+\]/AC_INIT([ipx-utils], [${VERSION}]/" configure.ac + + - name: Generate build system + run: | + set -e + autopoint --force + autoreconf -fi + + - name: Configure + run: | + set -e + ./configure --prefix=/usr + + - name: Build + run: | + set -e + make V=1 + + - name: Run distcheck + run: | + set -e + make distcheck + + - name: Collect dist archives + id: pkg + env: + DIST_BASENAME: ${{ steps.version.outputs.dist_basename }} + run: | + set -e + + mkdir -p dist-artifacts + + for archive in ${DIST_BASENAME}.tar.gz ${DIST_BASENAME}.tar.xz; do + if [ -f "$archive" ]; then + cp -av "$archive" dist-artifacts/ + fi + done + + if ! ls dist-artifacts/*.tar.* >/dev/null 2>&1; then + echo "No dist archives found" + ls -la + exit 1 + fi + + echo "files<> "$GITHUB_OUTPUT" + realpath dist-artifacts/*.tar.* >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + + echo "names<> "$GITHUB_OUTPUT" + basename -a dist-artifacts/*.tar.* >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + + ls -lh dist-artifacts + + for archive in dist-artifacts/*.tar.*; do + echo + echo "Archive content preview: $archive" + case "$archive" in + *.tar.gz) tar -tzf "$archive" | sed -n '1,25p' ;; + *.tar.xz) tar -tJf "$archive" | sed -n '1,25p' ;; + esac + done + + - name: Decide release target + id: target + env: + REF_TYPE: ${{ gitea.ref_type || github.ref_type }} + REF_NAME: ${{ gitea.ref_name || github.ref_name }} + SHA: ${{ gitea.sha || github.sha }} + run: | + set -e + + if [ "$REF_TYPE" = "tag" ]; then + echo "tag=$REF_NAME" >> "$GITHUB_OUTPUT" + echo "name=$REF_NAME" >> "$GITHUB_OUTPUT" + echo "prerelease=false" >> "$GITHUB_OUTPUT" + else + SHORT_SHA="$(printf '%s' "$SHA" | cut -c1-7)" + echo "tag=development" >> "$GITHUB_OUTPUT" + echo "name=development ($REF_NAME @ $SHORT_SHA)" >> "$GITHUB_OUTPUT" + echo "prerelease=true" >> "$GITHUB_OUTPUT" + fi + + - name: Create or update release + env: + GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }} + REL_TAG: ${{ steps.target.outputs.tag }} + REL_NAME: ${{ steps.target.outputs.name }} + REL_PRERELEASE: ${{ steps.target.outputs.prerelease }} + run: | + set -e + + RELEASE_JSON="$(curl -fsS \ + -H "Authorization: token ${GITEA_TOKEN}" \ + "${GITEA_API}/repos/${OWNER}/${REPO}/releases/tags/${REL_TAG}" || true)" + + if [ -z "$RELEASE_JSON" ]; then + RELEASE_JSON="$(curl -fsS -X POST \ + -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Content-Type: application/json" \ + "${GITEA_API}/repos/${OWNER}/${REPO}/releases" \ + -d "$(jq -n \ + --arg tag "$REL_TAG" \ + --arg name "$REL_NAME" \ + --argjson prerelease "$REL_PRERELEASE" \ + '{tag_name:$tag,name:$name,draft:false,prerelease:$prerelease}')" )" + else + RELEASE_ID="$(printf '%s' "$RELEASE_JSON" | jq -r '.id')" + RELEASE_JSON="$(curl -fsS -X PATCH \ + -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Content-Type: application/json" \ + "${GITEA_API}/repos/${OWNER}/${REPO}/releases/${RELEASE_ID}" \ + -d "$(jq -n \ + --arg tag "$REL_TAG" \ + --arg name "$REL_NAME" \ + --argjson prerelease "$REL_PRERELEASE" \ + '{tag_name:$tag,name:$name,draft:false,prerelease:$prerelease}')" )" + fi + + echo "$RELEASE_JSON" > release.json + + - name: Delete old development assets + if: ${{ steps.target.outputs.tag == 'development' }} + env: + GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }} + run: | + set -e + + RELEASE_ID="$(jq -r '.id' release.json)" + + ASSET_IDS="$(curl -fsS \ + -H "Authorization: token ${GITEA_TOKEN}" \ + "${GITEA_API}/repos/${OWNER}/${REPO}/releases/${RELEASE_ID}" \ + | jq -r '.assets[]? | .id')" + + if [ -z "$ASSET_IDS" ]; then + echo "No old development assets to delete." + exit 0 + fi + + for ASSET_ID in $ASSET_IDS; do + echo "Deleting old development asset id=${ASSET_ID}" + curl -fsS -X DELETE \ + -H "Authorization: token ${GITEA_TOKEN}" \ + "${GITEA_API}/repos/${OWNER}/${REPO}/releases/${RELEASE_ID}/assets/${ASSET_ID}" + done + + - name: Delete old assets with same names if present + env: + GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }} + run: | + set -e + + RELEASE_ID="$(jq -r '.id' release.json)" + + for FILE in dist-artifacts/*.tar.*; do + NAME="$(basename "$FILE")" + ASSET_ID="$(curl -fsS \ + -H "Authorization: token ${GITEA_TOKEN}" \ + "${GITEA_API}/repos/${OWNER}/${REPO}/releases/${RELEASE_ID}" \ + | jq -r --arg NAME "$NAME" '.assets[]? | select(.name==$NAME) | .id' \ + | head -n1)" + + if [ -n "$ASSET_ID" ]; then + echo "Deleting old asset: $NAME" + curl -fsS -X DELETE \ + -H "Authorization: token ${GITEA_TOKEN}" \ + "${GITEA_API}/repos/${OWNER}/${REPO}/releases/${RELEASE_ID}/assets/${ASSET_ID}" + fi + done + + - name: Upload tarballs to release + env: + GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }} + run: | + set -e + + RELEASE_ID="$(jq -r '.id' release.json)" + + for FILE in dist-artifacts/*.tar.*; do + NAME="$(basename "$FILE")" + echo "Uploading $NAME" + curl -fsS -X POST \ + -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Content-Type: application/octet-stream" \ + --data-binary @"${FILE}" \ + "${GITEA_API}/repos/${OWNER}/${REPO}/releases/${RELEASE_ID}/assets?name=${NAME}" + done diff --git a/Makefile.am b/Makefile.am index 97b26af..3bc278d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,58 +1,77 @@ +ACLOCAL_AMFLAGS = -I m4 + +SUBDIRS = po + AM_CFLAGS = -Wall -Wextra sbin_PROGRAMS = \ - ipx_configure \ - ipx_interface \ - ipx_internal_net \ - ipx_route \ - ipx_cmd \ - ipx_dump \ - ipx_parse + ipx_configure \ + ipx_interface \ + ipx_internal_net \ + ipx_route \ + ipx_cmd \ + ipx_dump \ + ipx_parse ipx_configure_SOURCES = \ - src/ipx_configure.c + src/nls.h \ + src/ipx_configure.c ipx_interface_SOURCES = \ - src/ipxutil.c \ - src/ipx_interface.c + src/nls.h \ + src/ipxutil.h \ + src/ipxutil.c \ + src/ipx_interface.c ipx_internal_net_SOURCES = \ - src/ipxutil.c \ - src/ipx_internal_net.c + src/nls.h \ + src/ipxutil.h \ + src/ipxutil.c \ + src/ipx_internal_net.c ipx_route_SOURCES = \ - src/ipxutil.c \ - src/ipx_route.c + src/nls.h \ + src/ipxutil.h \ + src/ipxutil.c \ + src/ipx_route.c ipx_cmd_SOURCES = \ - src/ipx_cmd.c + src/nls.h \ + src/netlink.h \ + src/ipx_cmd.c ipx_dump_SOURCES = \ - tools/ipxutil.c \ - tools/ipxdump.c + tools/nls.h \ + tools/ipxutil.h \ + tools/ipxutil.c \ + tools/ipxdump.c ipx_parse_SOURCES = \ - tools/ipxutil.c \ - tools/ipxparse.c + tools/nls.h \ + tools/ipxutil.h \ + tools/ipxutil.c \ + tools/ipxparse.c man_MANS = \ - docs/ipx_configure.8 \ - docs/ipx_interface.8 \ - docs/ipx_internal_net.8 \ - docs/ipx_route.8 \ - docs/ipx_cmd.8 + docs/ipx_configure.8 \ + docs/ipx_interface.8 \ + docs/ipx_internal_net.8 \ + docs/ipx_route.8 \ + docs/ipx_cmd.8 samples_files = \ - Samples/ipxrcv.c \ - Samples/ipxsend.c \ - Samples/rip.c \ - Samples/sap.c \ - Samples/samples.h + Samples/ipxrcv.c \ + Samples/ipxsend.c \ + Samples/rip.c \ + Samples/sap.c \ + Samples/samples.h EXTRA_DIST = \ - $(man_MANS) \ - $(samples_files) \ - autogen.sh \ - scripts/config.ipx \ - scripts/init.ipx -SUBDIRS = po + $(man_MANS) \ + $(samples_files) \ + autogen.sh \ + scripts/config.ipx \ + scripts/init.ipx + +DISTCLEANFILES = \ + po/stamp-po diff --git a/configure.ac b/configure.ac index 92f8dbd..f522b7c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,33 +1,22 @@ - -dnl Define a config.h string from a configure directory variable. -AC_DEFUN([AC_DEFINE_DIR], [ - prefix_NONE= - exec_prefix_NONE= - test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix - test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix - ac_define_dir=`eval echo [$]$2` - ac_define_dir=`eval echo [$]ac_define_dir` - AC_DEFINE_UNQUOTED([$1], ["$ac_define_dir"], [$3]) - test "$prefix_NONE" && prefix=NONE - test "$exec_prefix_NONE" && exec_prefix=NONE -]) - AC_INIT([ipx-utils], [1.2], [mario.fetka@disconnected-by-peer.at]) +AC_CONFIG_SRCDIR([src/ipx_configure.c]) +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_MACRO_DIRS([m4]) + +AM_INIT_AUTOMAKE([foreign subdir-objects dist-xz]) AM_GNU_GETTEXT([external]) AM_GNU_GETTEXT_VERSION([0.21]) -AM_INIT_AUTOMAKE([subdir-objects]) -AC_CONFIG_SRCDIR([src/ipx_configure.c]) -AC_CONFIG_HEADERS([config.h]) - -AC_CONFIG_FILES([Makefile po/Makefile.in]) +AC_PROG_CC AC_CHECK_HEADERS([libintl.h]) AC_SEARCH_LIBS([gettext], [intl]) AC_CHECK_FUNCS([gettext bindtextdomain textdomain]) -AC_DEFINE_DIR([LOCALEDIR], [localedir], [Define location of message catalogs]) -AC_PROG_CC -AM_PROG_CC_C_O +AC_DEFINE_UNQUOTED([LOCALEDIR], ["${datadir}/locale"], [Define location of message catalogs]) +AC_CONFIG_FILES([ + Makefile + po/Makefile.in +]) AC_OUTPUT