pipeline {
    agent { label 'docker' }

    options {
        timeout(time: 8, unit: 'HOURS')
        disableConcurrentBuilds()
    }

    environment {
        IMAGE    = 'collabora-snap-builder'
        CONTAINER = "snap-builder-${BUILD_NUMBER}"
        VOLUME   = 'collabora-snap-build'
        EXEC     = "docker exec -e PATH=/snap/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    }

    stages {
        stage('Build Docker image') {
            steps {
                dir('snap') {
                    sh 'docker build -t $IMAGE .'
                }
            }
        }

        stage('Start container') {
            steps {
                sh '''
                    docker rm -f $CONTAINER 2>/dev/null || true
                    docker run -d --privileged \
                        --name $CONTAINER \
                        -v $WORKSPACE:/src:ro \
                        -v $VOLUME:/build \
                        $IMAGE
                '''
                // Wait for snapd
                sh '''
                    for i in $(seq 1 60); do
                        docker exec $CONTAINER snap version && break
                        sleep 1
                    done
                '''
            }
        }

        stage('Install snapcraft') {
            steps {
                sh '''
                    if ! $EXEC $CONTAINER bash -c 'command -v snapcraft'; then
                        docker exec $CONTAINER snap install snapcraft --classic
                    fi
                '''
            }
        }

        stage('Build snap') {
            steps {
                sh '''
                    $EXEC $CONTAINER rsync -a \
                        --exclude='.git' \
                        --exclude='node_modules' \
                        --exclude='parts' \
                        --exclude='stage' \
                        --exclude='prime' \
                        --exclude='snap/output' \
                        --exclude='engine/workdir' \
                        --exclude='engine/instdir' \
                        --exclude='engine/inst' \
                        --exclude='engine/autom4te.cache' \
                        --exclude='engine/translations' \
                        --exclude='browser/dist' \
                        --exclude='browser/node_modules' \
                        /src/ /build/

                    # Carry the host's commit hash into the build. configure.ac
                    # prefers dist_git_hash over `git log` (which would fail
                    # anyway, since the rsync excludes .git), so without this
                    # file the About dialog shows "git hash: <version-string>".
                    # Skip if /build already has a dist_git_hash from a release
                    # tarball, and skip if the host isn't a git checkout.
                    if ! $EXEC $CONTAINER test -f /build/dist_git_hash; then
                        GIT_HASH=$(cd $WORKSPACE && git log -1 --format=%h --abbrev=10 2>/dev/null)
                        if [ -n "$GIT_HASH" ]; then
                            $EXEC $CONTAINER bash -c "echo '$GIT_HASH' > /build/dist_git_hash"
                        fi
                    fi

                    $EXEC -w /build $CONTAINER \
                        snapcraft --destructive-mode --verbosity=verbose
                '''
            }
        }

        stage('Extract snap') {
            steps {
                sh '''
                    mkdir -p $WORKSPACE/output
                    docker cp $CONTAINER:/build/collabora-office_*.snap \
                        $WORKSPACE/output/
                '''
                archiveArtifacts artifacts: 'output/*.snap', fingerprint: true
            }
        }
    }

    post {
        always {
            sh "docker stop $CONTAINER 2>/dev/null || true"
            sh "docker rm $CONTAINER 2>/dev/null || true"
        }
    }
}
