Coder Social home page Coder Social logo

Comments (14)

sebastianfeldmann avatar sebastianfeldmann commented on August 30, 2024

Can you show the configuration part of the Condition and tell me the git operation you are running.
Currently it's a bit vague in order to make any conclusions.

Please provide:

  • complete hook or at least action config
  • executed git command

Be sure that your container can execute git and has access to the .git directory.

from captainhook.

cegento avatar cegento commented on August 30, 2024

complete hook or at least action config

The part of the configuration:

{
"config": {
 "run-mode": "docker",
 "run-exec": "docker exec docker_container_1"
},
"pre-push": {
        "enabled": true,
        "actions": [
            {
                "action": "composer run test",
                "options": [],
                "conditions": [
                    {
                        "exec": "or",
                        "args": [
                            {
                                "exec": "\\CaptainHook\\App\\Hook\\Condition\\FileChanged\\OfType",
                                "args": [
                                    "php"
                                ]
                            },
                            {
                                "exec": "\\CaptainHook\\App\\Hook\\Condition\\FileChanged\\OfType",
                                "args": [
                                    "phtml"
                                ]
                            }
                        ]
                    }
                ]
            }
        ]
    }
 }

executed git command

The command i ran:
git push

Be sure that your container can execute git and has access to the .git directory.

Yes it has access to .git and it can execute git push correctly (if hooks disabled)

from captainhook.

sebastianfeldmann avatar sebastianfeldmann commented on August 30, 2024

The question is, where do you execute git push?
Within the container, or one the host system?

If you run git commands on the host system and execute the Cap'n inside a container you have to make sure that the Cap'n inside that container has access to a git executable and has access to the .git directory.
The Cap'n executes git commands in the background to make decisions.

There is another problem however.
You can not use the StagedFiles conditions in pre-push hooks.
Staging (add to index) only works in pre-commit hooks.

    /**
     * Return the FileStaged\OfType restriction information
     *
     * @return \CaptainHook\App\Hook\Restriction
     */
    public static function getRestriction(): Restriction
    {
        return Restriction::fromArray([Hooks::PRE_COMMIT]);
    }

You need to use FileChanged\OfType because that is applicable for pre-push hooks.

   /**
     * Return the FileChanged\OfType restriction information
     *
     * @return \CaptainHook\App\Hook\Restriction
     */
    public static function getRestriction(): Restriction
    {
        return Restriction::fromArray([Hooks::PRE_PUSH, Hooks::POST_CHECKOUT, Hooks::POST_MERGE, Hooks::POST_REWRITE]);
    }

Maybe I should echo a warning if a condition is wrongly used.

But as mentioned before, you have to make sure that the container executing CaptainHook has access to git and the .git directory.

from captainhook.

cegento avatar cegento commented on August 30, 2024

The question is, where do you execute git push?

I run it on the host system (outside of docker)

You can not use the StagedFiles conditions in pre-push hooks.

My bad, i actually ment \CaptainHook\App\Hook\Condition\FileChanged\OfType (at least this was what i used when testing it). Copy past error since i was in the wrong branch.

If you run git commands on the host system and execute the Cap'n inside a container you have to make sure that the Cap'n inside that container has access to a git executable and has access to the .git directory.

Testet it by putting echo shell_exec("cat .git/HEAD"); into the captainhook code. It correctly outputted the file data

from captainhook.

sebastianfeldmann avatar sebastianfeldmann commented on August 30, 2024

Another test you have to do is to use git status as an action and see if that runs.
Only if the Cap'n has access to git it can execute properly.

from captainhook.

cegento avatar cegento commented on August 30, 2024

Another test you have to do is to use git status as an action and see if that runs.

Tried it by putting echo shell_exec("git status") into the code and it worked

from captainhook.

sebastianfeldmann avatar sebastianfeldmann commented on August 30, 2024

Have you tried to run the Cap'n in debug mode?

captainhook -vvv

or in your configuration

  "config": {
    "verbosity": "debug"
  }

from captainhook.

cegento avatar cegento commented on August 30, 2024

I have now added "verbosity": "debug" to the config part. I must state that the output didn't really change that much except that messages like No plugins to execute for: beforeHook popped up.

from captainhook.

sebastianfeldmann avatar sebastianfeldmann commented on August 30, 2024

Can you post the full output? Of course you can remove all sensitive data like path or command options or even commands.

Just to recap. You are running git push and would expect the conditions to be true and want composer run test to be executed. Right?

from captainhook.

cegento avatar cegento commented on August 30, 2024

Can you post the full output? Of course you can remove all sensitive data like path or command options or even commands.

user@user:/var/www/project$ git push
pre-push: 
No plugins to execute for: beforeHook
 - composer run test                                                :  skipped
 - bin/magento module:status --enabled | grep -e App_ -e Stat... : 
No plugins to execute for: beforeAction

[From now on it just gets pushed regularely, therefore only git log]

Just to recap. You are running git push and would expect the conditions to be true and want composer run test to be executed. Right?

Exactly. For more context, i have committed a file with a .php ending to the local repository already and therefore i would expect composer run test to be executed inside the docker container (but as you see, it gets skipped).

from captainhook.

cegento avatar cegento commented on August 30, 2024

I have decided to make a detailed step by step list so you can reproduce it too.

  1. Create a folder called test
  2. Go in it and run git init and upload it on github
  3. Install composer on the hostmachine + php 8.1.2
  4. Install docker and docker-compose if you dont have it
  5. Create a docker-compse.yml file and put the following in it:
services:
  php-fpm:
    image: 'bitnami/php-fpm'
    volumes:
      - ./:/app
  1. run docker-compose up
  2. Install captainhook with composer require captainhook/captainhook
  3. Add a captainhook.json with the following content. Note that test_php-fpm_1 might have a different name on your machine. If you dont know the name, type docker container list and replace it with the name of the docker container of php-fpm.
{
    "config": {
        "run-mode": "docker",
        "run-exec": "docker exec test_php-fpm_1" 
    },
    "pre-push": {
        "enabled": true,
        "actions": [
            {
                "action": "echo \"test\"",
                "options": [],
                "conditions": [
                    {
                        "exec": "or",
                        "args": [
                            {
                                "exec": "\\CaptainHook\\App\\Hook\\Condition\\FileChanged\\OfType",
                                "args": [
                                    "php"
                                ]
                            },
                            { 
                                "exec": "\\CaptainHook\\App\\Hook\\Condition\\FileChanged\\OfType",
                                "args": [
                                    "phtml"
                                ]
                            }
                        ]
                    }
                ]
            },
            {
                "action": "exit",
                "options": []
            }
        ]
    }
}

  1. Then run vendor/bin/captainhook install in the git repository path
  2. Add a .gitignore file and put vendor in it.
  3. Push everything so that you have a clean git enviroment
  4. Add a .php file that is called lets say "test.php".
  5. run git add .
  6. run git commit -m "Test"
  7. run git push
  8. From now on you will see that the pre-push action echo "test" will be skipped, even though, there is a new php file.

from captainhook.

sebastianfeldmann avatar sebastianfeldmann commented on August 30, 2024

So if I do everything as you described I can reproduce your error.

If I add the following to the configuration

"pre-push": {
        "enabled": true,
        "actions": [
            {
                "action": "git status"
            },
            {
                "action": "echo \"TEST TEST\"",
                "options": [],
                "conditions": [
                    {
                        "exec": "or",
                        "args": [
                            {
                                "exec": "\\CaptainHook\\App\\Hook\\Condition\\FileChanged\\OfType",
                                "args": [
                                    "php"
                                ]
                            },
                            {
                                "exec": "\\CaptainHook\\App\\Hook\\Condition\\FileChanged\\OfType",
                                "args": [
                                    "phtml"
                                ]
                            }
                        ]
                    }
                ]
            },
            {
                "action": "\\CaptainHook\\App\\Hook\\Debug"
            }
        ]
    }

I get the following error.

failed to execute: git status

sh: 1: git: not found

That means the container does not have access to git. Without access to git the Captain can not figure out what files have changed. I'm currently investigating why the Condition is not failing, because without access to git everything should crash and scream "NO GIT". I will investigate and hopefully find the problem why it doesn't.

from captainhook.

sebastianfeldmann avatar sebastianfeldmann commented on August 30, 2024

Ok the problem is the docker exec you are using.

The start and end point of pushes is communicated via stdin to the hook.
If you delegate the hook execution to a container you have to forward the stdin by using the -i option.

    "run-exec": "docker exec -i dummy-php-fpm-1"

That worked in my case. At least now the Cap'n sees the start and end point of the push and tries to figure out what changed. If the info is missing the Cap'n expects a basically empty push so he isn't doing anything, That's why the Condition does not trigger.

It works to the point were the Cap'n tries to figure out what changed. Because for that the Cap'n uses some git commands and without access to git it does not work and crashes.

But as soon you pass the stdin to your container and the container has access to git it should work as expected.

from captainhook.

cegento avatar cegento commented on August 30, 2024

Thank you for helping!, it now works for me too

from captainhook.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.