continuous-integrationgitlabgitlab-cirmreadlink

How to delete target of symbolic link in Gitlab CI script?


I have a problem setting up .gitlab-ci.yml file. I want to delete old commits, so I have only the latest and previous commit available on a (Debian) server.

For some reason, when the script is executed, it doesn't behave as expected - the commits are switched correctly, but the old one is persist in the folder and is not deleted with rm -rf $(readlink <link>)

However, if I SSH on the server with the same user and do the exact same steps, rm -rf $(readlink <link>) successfully deletes the actual symlink target (expected behavior). When the same thing is done from CI script, the target is not deleted.

Maybe I missed some variable escaping, or parenthesis?

This is my (trimmed) .gitlab-ci.yml file:

variables:
    SSH_USER: "user@server"
    PROJECT_DIR: "/domains/example.com/project-name"
    DEPLOY_DIR: "${PROJECT_DIR}/deploy"
    STAGING_TEMP_DIR: "${PROJECT_DIR}/staging-temp"
    # is this correct?
    DELETE_STAGING_TEMP: "'$$(readlink -f ${STAGING_TEMP_DIR})'"

stages:
    - build
    - deploy
    - post-deploy

Post Deploy staging:
    stage: post-deploy
    script:
        # switch last version
        - ssh $SSH_USER mv ${PROJECT_DIR}/staging-previous ${STAGING_TEMP_DIR} || true
        - ssh $SSH_USER mv ${PROJECT_DIR}/staging-latest ${PROJECT_DIR}/staging-previous || true
        - ssh $SSH_USER rm -rf ${DELETE_STAGING_TEMP}
        - ssh $SSH_USER unlink ${STAGING_TEMP_DIR} || true
        - ssh $SSH_USER ln -s ${DEPLOY_DIR}/${CI_COMMIT_REF_NAME}/${CI_COMMIT_SHA} ${PROJECT_DIR}/staging-latest

I also tried this variant:

variables:
    SSH_USER: "user@server"
    PROJECT_DIR: "/domains/example.com/project-name"
    DEPLOY_DIR: "${PROJECT_DIR}/deploy"
    STAGING_TEMP_DIR: "${PROJECT_DIR}/staging-temp"

Post Deploy staging:
    stage: post-deploy
    script:            
        # switch last version
        - ssh $SSH_USER mv ${PROJECT_DIR}/staging-previous ${STAGING_TEMP_DIR} || true
        - ssh $SSH_USER mv ${PROJECT_DIR}/staging-latest ${PROJECT_DIR}/staging-previous || true      
        # is this correct? 
        - ssh $SSH_USER rm -rf "$(readlink -f ${STAGING_TEMP_DIR})"
        - ssh $SSH_USER unlink ${STAGING_TEMP_DIR} || true
        - ssh $SSH_USER ln -s ${DEPLOY_DIR}/${CI_COMMIT_REF_NAME}/${CI_COMMIT_SHA} ${PROJECT_DIR}/staging-latest

Just a note: ${PROJECT_DIR}/staging-previous and ${PROJECT_DIR}/staging-latest are symlinks to commits.

Does anyone have similar issue? Or do you use other methods for deleting old (no more needed) commits?


Solution

  • Finally found a solution - it was bad escaping of backticks `

    Post Deploy STAGING:
        stage: post-deploy
        script:
            # checks if current commit is already set up as staging-latest
            # if not, then this is new release, so switch last version:
            # - move staging-previous to temp
            # - move staging-latest to staging-previous
            # - delete the content of temp dir and unlink temp
            - >
                ssh $SSH_USER "if [ \"\`readlink ${PROJECT_DIR}/staging-latest\`\" != \"${DEPLOY_DIR}/${CI_COMMIT_REF_NAME}/${CI_COMMIT_SHA}\" ];
                then \`mv ${PROJECT_DIR}/staging-previous ${STAGING_TEMP_DIR} || true;
                mv ${PROJECT_DIR}/staging-latest ${PROJECT_DIR}/staging-previous || true\`;
                rm -rf \`readlink -f ${STAGING_TEMP_DIR}\`;
                unlink ${STAGING_TEMP_DIR} || true;
                fi;"
            - ssh $SSH_USER ln -s ${DEPLOY_DIR}/${CI_COMMIT_REF_NAME}/${CI_COMMIT_SHA} ${PROJECT_DIR}/staging-latest || true