Skip to content

Build and Release Go-Easy #2

Build and Release Go-Easy

Build and Release Go-Easy #2

name: Build and Release Go-Easy
on:
schedule:
# Check for updates daily at midnight UTC
- cron: '0 0 * * *'
workflow_dispatch:
inputs:
force_build:
description: 'Force build even if no changes are detected'
type: boolean
default: false
version_suffix:
description: 'Custom version suffix (default is -easy)'
type: string
default: '-easy'
skip_release:
description: 'Skip creating GitHub release'
type: boolean
default: false
jobs:
check-for-changes:
runs-on: ubuntu-latest
outputs:
has_changes: ${{ steps.check_changes.outputs.has_changes }}
go_version: ${{ steps.extract_version.outputs.go_version }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Check repository structure
run: |
echo "Checking required files..."
ls -R src/cmd/compile/internal/base/
ls -R src/cmd/compile/internal/types2/
ls -R src/cmd/dist/
shell: bash
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.23.7' # Using a more recent version as bootstrap compiler
check-latest: true
- name: Verify Go Version
run: go version
- name: Clone Go repository
run: |
git clone --depth=1 https://github.com/golang/go golang-repo
cd golang-repo
echo "GO_REPO_COMMIT=$(git rev-parse HEAD)" >> $GITHUB_ENV
- name: Check if new changes exist in upstream
id: check_changes
run: |
# If force_build is set to true, always build
if [[ "${{ github.event.inputs.force_build }}" == "true" ]]; then
echo "Force build requested, proceeding with build"
echo "has_changes=true" >> $GITHUB_OUTPUT
echo "$GO_REPO_COMMIT" > last_processed_commit.txt
exit 0
fi
# Check if we have a file that tracks the last processed commit
if [ -f last_processed_commit.txt ]; then
LAST_PROCESSED_COMMIT=$(cat last_processed_commit.txt)
echo "Last processed commit: $LAST_PROCESSED_COMMIT"
if [ "$LAST_PROCESSED_COMMIT" == "$GO_REPO_COMMIT" ]; then
echo "No new changes in golang/go repository"
echo "has_changes=false" >> $GITHUB_OUTPUT
else
echo "New changes detected in golang/go repository"
echo "has_changes=true" >> $GITHUB_OUTPUT
echo "$GO_REPO_COMMIT" > last_processed_commit.txt
fi
else
echo "First time running workflow or tracking file not found"
echo "has_changes=true" >> $GITHUB_OUTPUT
echo "$GO_REPO_COMMIT" > last_processed_commit.txt
fi
- name: Extract Go version
id: extract_version
if: steps.check_changes.outputs.has_changes == 'true'
run: |
cd golang-repo
# Check VERSION file first
if [ -f VERSION ]; then
GO_VERSION=$(cat VERSION | head -n 1)
else
# Extract version from src/internal/goversion/goversion.go if VERSION doesn't exist
GOVERSION_SOURCE=$(cat src/internal/goversion/goversion.go)
VERSION_NUM=$(echo "$GOVERSION_SOURCE" | grep -oP 'const Version = \K[0-9]+')
GO_VERSION="go1.${VERSION_NUM}"
# Check if this is a release branch
if git branch -r | grep -q "release-branch.go1.${VERSION_NUM}"; then
GO_VERSION="go1.${VERSION_NUM}"
else
# This is development, use full commit hash
COMMIT_HASH=$(git rev-parse --short HEAD)
COMMIT_DATE=$(git show -s --format=%ci HEAD | cut -d' ' -f1)
GO_VERSION="devel ${GO_VERSION}-${COMMIT_HASH} ${COMMIT_DATE}"
fi
fi
# Format the version string for the release name
RELEASE_VERSION=$(echo "$GO_VERSION" | sed 's/^go//')
echo "go_version=${RELEASE_VERSION}" >> $GITHUB_OUTPUT
echo "Go version: ${GO_VERSION}"
echo "Release version: ${RELEASE_VERSION}"
- name: Save commit tracking file
if: steps.check_changes.outputs.has_changes == 'true'
uses: actions/upload-artifact@v4
with:
name: commit-tracking
path: last_processed_commit.txt
build:
needs: check-for-changes
if: needs.check-for-changes.outputs.has_changes == 'true'
strategy:
matrix:
include:
# Linux builds
- os: ubuntu-latest
platform: linux
arch: amd64
- os: ubuntu-latest
platform: linux
arch: 386
- os: ubuntu-latest
platform: linux
arch: arm64
- os: ubuntu-latest
platform: linux
arch: arm
# macOS builds
- os: macos-latest
platform: darwin
arch: amd64
- os: macos-latest
platform: darwin
arch: arm64
# Windows builds
- os: windows-latest
platform: windows
arch: amd64
- os: windows-latest
platform: windows
arch: 386
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.23.7' # Using a more recent version as bootstrap compiler
check-latest: true
- name: Verify Go Version
run: go version
- name: Clone Go repository
run: |
git clone --depth=1 https://github.com/golang/go golang-repo
- name: Download commit tracking file
uses: actions/download-artifact@v4
with:
name: commit-tracking
- name: Apply Go-Easy changes (Unix)
if: matrix.platform != 'windows'
run: |
# Apply our custom changes for Go-Easy
cp -f src/cmd/compile/internal/base/print.go golang-repo/src/cmd/compile/internal/base/print.go
cp -f src/cmd/compile/internal/types2/errors.go golang-repo/src/cmd/compile/internal/types2/errors.go
cp -f src/cmd/compile/internal/types2/api.go golang-repo/src/cmd/compile/internal/types2/api.go
cp -f src/cmd/dist/build.go golang-repo/src/cmd/dist/build.go
cd golang-repo
echo "Set GOOS=${{ matrix.platform }} and GOARCH=${{ matrix.arch }}"
- name: Apply Go-Easy changes (Windows)
if: matrix.platform == 'windows'
shell: pwsh
run: |
# Apply our custom changes for Go-Easy
Copy-Item -Force src\cmd\compile\internal\base\print.go golang-repo\src\cmd\compile\internal\base\print.go
Copy-Item -Force src\cmd\compile\internal\types2\errors.go golang-repo\src\cmd\compile\internal\types2\errors.go
Copy-Item -Force src\cmd\compile\internal\types2\api.go golang-repo\src\cmd\compile\internal\types2\api.go
Copy-Item -Force src\cmd\dist\build.go golang-repo\src\cmd\dist\build.go
cd golang-repo
echo "Set GOOS=${{ matrix.platform }} and GOARCH=${{ matrix.arch }}"
- name: Build Go for Linux/macOS
if: matrix.platform != 'windows'
run: |
# Verify Go version first
go version
GOPATH=$(which go)
GOROOT=$(dirname $(dirname $GOPATH))
echo "Go executable path: $GOPATH"
echo "GOROOT: $GOROOT"
# Set the bootstrap Go root – this is key according to the Go docs
export GOROOT_BOOTSTRAP=$GOROOT
echo "GOROOT_BOOTSTRAP: $GOROOT_BOOTSTRAP"
cd golang-repo
# Build Go using the official procedure
cd src
# Set cross-compilation environment variables
export CGO_ENABLED=0
export GO111MODULE=off
export GOTOOLCHAIN=local
export GOOS=${{ matrix.platform }}
export GOARCH=${{ matrix.arch }}
echo "Environment variables:"
echo "GOROOT_BOOTSTRAP: $GOROOT_BOOTSTRAP"
echo "CGO_ENABLED: $CGO_ENABLED"
echo "GO111MODULE: $GO111MODULE"
echo "GOTOOLCHAIN: $GOTOOLCHAIN"
echo "GOOS: $GOOS"
echo "GOARCH: $GOARCH"
./make.bash
- name: Build Go for Windows
if: matrix.platform == 'windows'
shell: pwsh
run: |
# Verify Go version first
go version
$goPath = (Get-Command go).Path
$goRoot = (Split-Path -Parent (Split-Path -Parent $goPath))
Write-Host "Go executable path: $goPath"
Write-Host "GOROOT: $goRoot"
# Set the bootstrap Go root as required
$env:GOROOT_BOOTSTRAP = $goRoot
Write-Host "GOROOT_BOOTSTRAP: $env:GOROOT_BOOTSTRAP"
cd golang-repo
# Build Go using the official documentation
cd src
# Set cross-compilation environment variables
$env:CGO_ENABLED = "0"
$env:GO111MODULE = "off"
$env:GOTOOLCHAIN = "local"
$env:GOOS = "${{ matrix.platform }}"
$env:GOARCH = "${{ matrix.arch }}"
Write-Host "Environment variables:"
Write-Host "GOROOT_BOOTSTRAP: $env:GOROOT_BOOTSTRAP"
Write-Host "CGO_ENABLED: $env:CGO_ENABLED"
Write-Host "GO111MODULE: $env:GO111MODULE"
Write-Host "GOTOOLCHAIN: $env:GOTOOLCHAIN"
Write-Host "GOOS: $env:GOOS"
Write-Host "GOARCH: $env:GOARCH"
.\make.bat
- name: Create package (Unix)
if: matrix.platform != 'windows'
run: |
cd golang-repo
# Create archive based on platform
GO_VERSION="${{ needs.check-for-changes.outputs.go_version }}"
VERSION_SUFFIX="${{ github.event.inputs.version_suffix || '-easy' }}"
ARCHIVE_NAME="go${GO_VERSION}${VERSION_SUFFIX}-${{ matrix.platform }}-${{ matrix.arch }}"
# Create a tar.gz archive for Linux/macOS
tar -czf ${ARCHIVE_NAME}.tar.gz go
echo "Created archive: ${ARCHIVE_NAME}.tar.gz"
mkdir -p ../dist
mv ${ARCHIVE_NAME}.tar.gz ../dist/
- name: Create package (Windows)
if: matrix.platform == 'windows'
shell: pwsh
run: |
cd golang-repo
$GO_VERSION = "${{ needs.check-for-changes.outputs.go_version }}"
$VERSION_SUFFIX = "${{ github.event.inputs.version_suffix || '-easy' }}"
$ARCHIVE_NAME = "go${GO_VERSION}${VERSION_SUFFIX}-${{ matrix.platform }}-${{ matrix.arch }}"
# Create a zip archive for Windows
7z a -tzip $ARCHIVE_NAME.zip go
Write-Host "Created archive: $ARCHIVE_NAME.zip"
New-Item -ItemType Directory -Force -Path ..\dist
Move-Item $ARCHIVE_NAME.zip ..\dist\
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: go-${{ matrix.platform }}-${{ matrix.arch }}
path: dist/
retention-days: 1
release:
needs: [check-for-changes, build]
runs-on: ubuntu-latest
if: needs.check-for-changes.outputs.has_changes == 'true' && github.event.inputs.skip_release != 'true'
steps:
- name: Download all build artifacts
uses: actions/download-artifact@v4
with:
path: ./artifacts
- name: Prepare release files
run: |
mkdir -p ./release-files
find ./artifacts -type f -not -path "*/commit-tracking/*" -exec cp {} ./release-files/ \;
ls -la ./release-files/
- name: Create or update release
uses: softprops/action-gh-release@v1
with:
name: "Go ${{ needs.check-for-changes.outputs.go_version }}${{ github.event.inputs.version_suffix || '-easy' }}"
tag_name: "v${{ needs.check-for-changes.outputs.go_version }}${{ github.event.inputs.version_suffix || '-easy' }}"
files: ./release-files/*
draft: false
prerelease: false
fail_on_unmatched_files: false
token: ${{ secrets.GITHUB_TOKEN }}
generate_release_notes: true